Fixes
This commit is contained in:
parent
f4fdc051b5
commit
a41ed9cb53
@ -64,10 +64,10 @@ server {
|
||||
try_files $uri @sfFront;
|
||||
}
|
||||
|
||||
#location /w2p/ {
|
||||
# proxy_pass http://tp:8080/w2p/;
|
||||
# proxy_temp_path /tmp/proxy;
|
||||
#}
|
||||
location /w2p/ {
|
||||
proxy_pass http://tp:8080/w2p/;
|
||||
proxy_temp_path /tmp/proxy;
|
||||
}
|
||||
|
||||
location @sfFront { # Symfony
|
||||
if ($request_method = 'OPTIONS') {
|
||||
|
||||
@ -41,8 +41,9 @@ class Barcode extends Node
|
||||
$compiler->raw(
|
||||
'
|
||||
$options = new \PSC\System\SettingsBundle\Barcode\QRGdWithLogoOptions();
|
||||
//$options->version = -1;
|
||||
$options->eccLevel = \chillerlan\QRCode\Common\EccLevel::M;
|
||||
$options->version = -1;
|
||||
$options->versionMax = 40;
|
||||
$options->eccLevel = \chillerlan\QRCode\Common\EccLevel::H;
|
||||
$options->outputType = \chillerlan\QRCode\Output\QROutputInterface::CUSTOM;
|
||||
if(isset($_options["cmyk"]) && $_options["cmyk"] == true) {
|
||||
$options->outputInterface = \PSC\System\SettingsBundle\Barcode\QRImagickCMYK::class;
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
namespace PSC\System\UpdateBundle\Migrations;
|
||||
|
||||
class Version20250613181212 extends Base
|
||||
class Version20250613181223 extends Base
|
||||
{
|
||||
public function migrateDatabase(): void
|
||||
{
|
||||
@ -11,7 +11,7 @@ class Version20250613181212 extends Base
|
||||
$this->entityManager->getConnection()->exec("alter table article modify column a6_xmlpageobjectsfile varchar(255) default null;");
|
||||
$this->entityManager->getConnection()->exec("alter table article modify column layouterid varchar(255) default null;");
|
||||
$this->entityManager->getConnection()->exec("alter table article modify column resale int(1) default null;");
|
||||
$this->entityManager->getConnection()->exec("alter table article modify column a6_resale_price float(20,2) default null;");
|
||||
$this->entityManager->getConnection()->exec("alter table article modify column a6_resale_price float(20,2) default 0;");
|
||||
$this->entityManager->getConnection()->exec("alter table article modify column render_new_preview_image int(1) default null;");
|
||||
$this->entityManager->getConnection()->exec("alter table article modify column render_new_preview_pdf int(1) default null;");
|
||||
$this->entityManager->getConnection()->exec("alter table article modify column render_new_preview_gallery int(1) default null;");
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
"name": "my-vue-app",
|
||||
"dependencies": {
|
||||
"@tailwindcss/vite": "^4.1.10",
|
||||
"@vueuse/core": "^13.3.0",
|
||||
"@vueuse/core": "^13.4.0",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"lucide-vue-next": "^0.514.0",
|
||||
@ -304,11 +304,11 @@
|
||||
|
||||
"@vue/tsconfig": ["@vue/tsconfig@0.7.0", "", { "peerDependencies": { "typescript": "5.x", "vue": "^3.4.0" }, "optionalPeers": ["typescript", "vue"] }, "sha512-ku2uNz5MaZ9IerPPUyOHzyjhXoX2kVJaVf7hL315DC17vS6IiZRmmCPfggNbU16QTvM80+uYYy3eYJB59WCtvg=="],
|
||||
|
||||
"@vueuse/core": ["@vueuse/core@13.3.0", "", { "dependencies": { "@types/web-bluetooth": "^0.0.21", "@vueuse/metadata": "13.3.0", "@vueuse/shared": "13.3.0" }, "peerDependencies": { "vue": "^3.5.0" } }, "sha512-uYRz5oEfebHCoRhK4moXFM3NSCd5vu2XMLOq/Riz5FdqZMy2RvBtazdtL3gEcmDyqkztDe9ZP/zymObMIbiYSg=="],
|
||||
"@vueuse/core": ["@vueuse/core@13.4.0", "", { "dependencies": { "@types/web-bluetooth": "^0.0.21", "@vueuse/metadata": "13.4.0", "@vueuse/shared": "13.4.0" }, "peerDependencies": { "vue": "^3.5.0" } }, "sha512-OnK7zW3bTq/QclEk17+vDFN3tuAm8ONb9zQUIHrYQkkFesu3WeGUx/3YzpEp+ly53IfDAT9rsYXgGW6piNZC5w=="],
|
||||
|
||||
"@vueuse/metadata": ["@vueuse/metadata@13.3.0", "", {}, "sha512-42IzJIOYCKIb0Yjv1JfaKpx8JlCiTmtCWrPxt7Ja6Wzoq0h79+YVXmBV03N966KEmDEESTbp5R/qO3AB5BDnGw=="],
|
||||
"@vueuse/metadata": ["@vueuse/metadata@13.4.0", "", {}, "sha512-CPDQ/IgOeWbqItg1c/pS+Ulum63MNbpJ4eecjFJqgD/JUCJ822zLfpw6M9HzSvL6wbzMieOtIAW/H8deQASKHg=="],
|
||||
|
||||
"@vueuse/shared": ["@vueuse/shared@13.3.0", "", { "peerDependencies": { "vue": "^3.5.0" } }, "sha512-L1QKsF0Eg9tiZSFXTgodYnu0Rsa2P0En2LuLrIs/jgrkyiDuJSsPZK+tx+wU0mMsYHUYEjNsuE41uqqkuR8VhA=="],
|
||||
"@vueuse/shared": ["@vueuse/shared@13.4.0", "", { "peerDependencies": { "vue": "^3.5.0" } }, "sha512-+AxuKbw8R1gYy5T21V5yhadeNM7rJqb4cPaRI9DdGnnNl3uqXh+unvQ3uCaA2DjYLbNr1+l7ht/B4qEsRegX6A=="],
|
||||
|
||||
"alien-signals": ["alien-signals@1.0.13", "", {}, "sha512-OGj9yyTnJEttvzhTUWuscOvtqxq5vrhF7vL9oS0xJ2mK0ItPYP1/y+vCFebfxoEyAz0++1AIwJ5CMr+Fk3nDmg=="],
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Vite + Vue + TS</title>
|
||||
<title>Calc</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app" class="w-screen h-screen"></div>
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@tailwindcss/vite": "^4.1.10",
|
||||
"@vueuse/core": "^13.3.0",
|
||||
"@vueuse/core": "^13.4.0",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"lucide-vue-next": "^0.514.0",
|
||||
|
||||
@ -13,42 +13,28 @@ import { Main } from '@/components/app/main'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ResizablePanelGroup
|
||||
id="handle-demo-group-1"
|
||||
direction="horizontal"
|
||||
class="h-full w-full"
|
||||
>
|
||||
<ResizablePanel id="" :default-size="25">
|
||||
<div class="flex flex-col h-full p-6">
|
||||
<Library />
|
||||
<Debug />
|
||||
</div>
|
||||
</ResizablePanel>
|
||||
<ResizableHandle id="" with-handle />
|
||||
<ResizablePanel id="" :default-size="75">
|
||||
<ResizablePanelGroup id="" direction="vertical">
|
||||
<ResizablePanel id="" :default-size="75">
|
||||
<ResizablePanelGroup id="" direction="horizontal">
|
||||
<ResizablePanel id="" :default-size="75">
|
||||
<div class="flex h-full p-6">
|
||||
<Main />
|
||||
</div>
|
||||
</ResizablePanel>
|
||||
<ResizableHandle id="" with-handle />
|
||||
<ResizablePanel id="" :default-size="25">
|
||||
<div class="flex h-full p-6">
|
||||
<ElementProperties />
|
||||
</div>
|
||||
</ResizablePanel>
|
||||
</ResizablePanelGroup>
|
||||
</ResizablePanel>
|
||||
<ResizableHandle id="" with-handle />
|
||||
<ResizablePanel id="" :default-size="25">
|
||||
<ElementDependency />
|
||||
</ResizablePanel>
|
||||
</ResizablePanelGroup>
|
||||
</ResizablePanel>
|
||||
</ResizablePanelGroup>
|
||||
<div class="w-scree h-screen">
|
||||
<ResizablePanelGroup
|
||||
id="handle-demo-group-1"
|
||||
direction="horizontal"
|
||||
class="h-full w-full"
|
||||
>
|
||||
<ResizablePanel id="" :default-size="15">
|
||||
<div class="flex flex-col gap-2 h-full">
|
||||
<Library />
|
||||
<Debug />
|
||||
</div>
|
||||
</ResizablePanel>
|
||||
<ResizableHandle id="" with-handle />
|
||||
<ResizablePanel id="" :default-size="85">
|
||||
<div class="flex h-full p-6 bg-slate-50">
|
||||
<Main />
|
||||
</div>
|
||||
</ResizablePanel>
|
||||
</ResizablePanelGroup>
|
||||
<ElementProperties />
|
||||
<ElementDependency />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@ -16,8 +16,10 @@ function restoreJson() {
|
||||
|
||||
<template>
|
||||
<div class="p-1">
|
||||
<Textarea v-model="store.json"/>
|
||||
<Button v-on:click="loadJson()">Load Json</Button>
|
||||
<Button v-on:click="restoreJson()">Restore Json</Button>
|
||||
<Textarea v-model="store.json" class="h-50"/>
|
||||
<div class="flex flex-row mt-2 gap-1">
|
||||
<Button class="grow" v-on:click="loadJson()">Load Json</Button>
|
||||
<Button class="grow" v-on:click="restoreJson()">Restore Json</Button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -21,8 +21,9 @@ const store = useElementStore()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="d-flex bg-slate-50 m-1 flex-wrap p-1 relative" v-for="border in borders" :key="border.uuid">
|
||||
<div class="flex flex-row gap-1">
|
||||
<div class="flex flex-col" v-for="border in borders" :key="border.uuid">
|
||||
<div class="flex flex-row items-center gap-2 border-l-3 border-black pt-1">
|
||||
<span class="w-5 flex-none"><hr class="bg-black h-1 border-0"/></span>
|
||||
<Input v-model="border.formula" placeholder="Formula"/>
|
||||
<Input v-model="border.calcValue" placeholder="CalcValue"/>
|
||||
<Input v-model="border.value" placeholder="Value"/>
|
||||
|
||||
@ -22,7 +22,7 @@ function addBorder(dep) {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-bind:class="{ 'invisible': store.isShowPropierties === false }" class=" w-full m-2 p-2">
|
||||
<div class=" w-full">
|
||||
<Border :borders="dependency.borders" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -21,8 +21,9 @@ function addBorder(dep) {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="d-flex flex-wrap p-2 relative" v-for="dep in dependencys" :key="dep.uuid">
|
||||
<div class="flex flex-row gap-1">
|
||||
<div class="d-flex flex-wrap relative ml-5 mr-5" v-for="dep in dependencys" :key="dep.uuid">
|
||||
<div class="flex flex-row gap-2 border-l-3 border-black pt-1">
|
||||
<span class="w-2 flex-none"></span>
|
||||
<Select v-model="dep.relation">
|
||||
<SelectTrigger class="w-[180px]">
|
||||
<SelectValue placeholder="Select Relation" />
|
||||
|
||||
@ -1,21 +1,55 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref, watch } from 'vue'
|
||||
import { useElementStore } from '@/stores/Items'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Dependency } from '.'
|
||||
import { default as DepModel } from '../../../model/Dependency.ts'
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from '@/components/ui/dialog'
|
||||
|
||||
const store = useElementStore()
|
||||
let openModal = ref(false)
|
||||
|
||||
function addDependency(event) {
|
||||
store.getActiveItem.addDependency(new DepModel());
|
||||
}
|
||||
|
||||
store.$subscribe((mutation, state) => {
|
||||
if(state.showDependency) {
|
||||
openModal.value = true
|
||||
}
|
||||
})
|
||||
watch(openModal, (newOpenModal) => {
|
||||
if(newOpenModal === false) {
|
||||
store.setShowDependency(false)
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-bind:class="{ 'invisible': store.isShowPropierties === false }" class="overflow-auto h-full w-full m-2 p-2">
|
||||
<Button v-on:click="addDependency($event)">Add Dependency</Button>
|
||||
<Dependency :dependencys="store.getActiveItem.dependencys" />
|
||||
</div>
|
||||
<Dialog class="w-full h-full" v-model:open="openModal">
|
||||
<DialogContent class="h-full">
|
||||
<DialogHeader>
|
||||
<DialogTitle>Dependencys</DialogTitle>
|
||||
<DialogDescription>
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<div class="overflow-auto h-full w-full">
|
||||
<Button v-on:click="addDependency($event)">Add Dependency</Button>
|
||||
<Dependency :dependencys="store.getActiveItem.dependencys" />
|
||||
</div>
|
||||
|
||||
<DialogFooter>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
@ -1,19 +1,99 @@
|
||||
<script lang="ts" setup>
|
||||
import { useElementStore } from '@/stores/Items';
|
||||
import InputElement from '@/model/InputElement';
|
||||
import InputElementProperties from '../properties/InputElement.vue';
|
||||
import { useElementStore } from '@/stores/Items'
|
||||
import InputElement from '@/model/InputElement'
|
||||
import SelectElement from '@/model/SelectElement'
|
||||
import HiddenElement from '@/model/HiddenElement'
|
||||
import TextElement from '@/model/TextElement'
|
||||
import Row from '@/model/Row'
|
||||
import TextareaElement from '@/model/TextareaElement'
|
||||
import HeadlineElement from '@/model/HeadlineElement'
|
||||
import InputElementProperties from '../properties/InputElement.vue'
|
||||
import SelectElementProperties from '../properties/SelectElement.vue'
|
||||
import HiddenElementProperties from '../properties/HiddenElement.vue'
|
||||
import TextElementProperties from '../properties/TextElement.vue'
|
||||
import TextareaElementProperties from '../properties/TextareaElement.vue'
|
||||
import HeadlineElementProperties from '../properties/HeadlineElement.vue'
|
||||
import RowProperties from '../properties/RowElement.vue'
|
||||
import { ref, watch } from 'vue'
|
||||
import {
|
||||
Sheet,
|
||||
SheetClose,
|
||||
SheetContent,
|
||||
SheetDescription,
|
||||
SheetFooter,
|
||||
SheetHeader,
|
||||
SheetTitle,
|
||||
SheetTrigger,
|
||||
} from '@/components/ui/sheet'
|
||||
|
||||
let openModal = ref(false)
|
||||
|
||||
let emit = defineEmits(['update:modelValue']);
|
||||
const store = useElementStore()
|
||||
|
||||
store.$subscribe((mutation, state) => {
|
||||
if(state.showProperties) {
|
||||
openModal.value = true
|
||||
}
|
||||
})
|
||||
watch(openModal, (newOpenModal) => {
|
||||
if(newOpenModal === false) {
|
||||
store.setShowProperties(false)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-bind:class="{ 'invisible': store.isShowPropierties === false }" class="flex flex-col w-full m-2">
|
||||
<InputElementProperties
|
||||
v-if="store.getActiveItem.type === 2"
|
||||
v-model="store.getActiveItem as InputElement"
|
||||
>
|
||||
</InputElementProperties>
|
||||
<Sheet v-model:open="openModal">
|
||||
<SheetContent>
|
||||
<SheetHeader>
|
||||
<SheetTitle>Properties</SheetTitle>
|
||||
<SheetDescription>
|
||||
</SheetDescription>
|
||||
</SheetHeader>
|
||||
<div class="flex flex-col w-full m-2">
|
||||
<HeadlineElementProperties
|
||||
v-if="store.getActiveItem.type === 6"
|
||||
v-model="store.getActiveItem as HeadlineElement"
|
||||
>
|
||||
</HeadlineElementProperties>
|
||||
|
||||
</div>
|
||||
<RowProperties
|
||||
v-if="store.getActiveItem.type === 7"
|
||||
v-model="store.getActiveItem as Row"
|
||||
>
|
||||
</RowProperties>
|
||||
|
||||
<TextareaElementProperties
|
||||
v-if="store.getActiveItem.type === 5"
|
||||
v-model="store.getActiveItem as TextareaElement"
|
||||
>
|
||||
</TextareaElementProperties>
|
||||
|
||||
<TextElementProperties
|
||||
v-if="store.getActiveItem.type === 4"
|
||||
v-model="store.getActiveItem as TextElement"
|
||||
>
|
||||
</TextElementProperties>
|
||||
|
||||
<SelectElementProperties
|
||||
v-if="store.getActiveItem.type === 3"
|
||||
v-model="store.getActiveItem as SelectElement"
|
||||
>
|
||||
</SelectElementProperties>
|
||||
|
||||
<InputElementProperties
|
||||
v-if="store.getActiveItem.type === 2"
|
||||
v-model="store.getActiveItem as InputElement"
|
||||
>
|
||||
</InputElementProperties>
|
||||
|
||||
<HiddenElementProperties
|
||||
v-if="store.getActiveItem.type === 1"
|
||||
v-model="store.getActiveItem as HiddenElement"
|
||||
>
|
||||
</HiddenElementProperties>
|
||||
</div>
|
||||
</SheetContent>
|
||||
</Sheet>
|
||||
</template>
|
||||
|
||||
@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<div class="p-5 m-2 h-full text-center">Empty</div>
|
||||
</template>
|
||||
@ -0,0 +1,32 @@
|
||||
<script lang="ts" setup>
|
||||
import HeadlineElement from '@/model/HeadlineElement';
|
||||
import { computed } from 'vue';
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { SquareDot } from 'lucide-vue-next';
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: HeadlineElement
|
||||
})
|
||||
|
||||
let emit = defineEmits(['update:modelValue']);
|
||||
|
||||
const theModel = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (value) => emit('update:modelValue', value),
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex gap-2 flex-row items-center content-center">
|
||||
<SquareDot />
|
||||
<h1 v-if="theModel.variant == 1" class="text-4xl">{{theModel.default}}</h1>
|
||||
<h6 v-else-if="theModel.variant == 6" class="text-base">{{theModel.default}}</h6>
|
||||
<h5 v-else-if="theModel.variant == 5" class="text-lg">{{theModel.default}}</h5>
|
||||
<h4 v-else-if="theModel.variant == 4" class="text-xl">{{theModel.default}}</h4>
|
||||
<h3 v-else-if="theModel.variant == 3" class="text-2xl">{{theModel.default}}</h3>
|
||||
<h2 v-else-if="theModel.variant == 2" class="text-3xl">{{theModel.default}}</h2>
|
||||
<h1 v-else class="text-4xl">{{theModel.default}}</h1>
|
||||
</div>
|
||||
</template>
|
||||
@ -0,0 +1,26 @@
|
||||
<script lang="ts" setup>
|
||||
import HiddenElement from '@/model/HiddenElement';
|
||||
import { computed } from 'vue';
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { SquareDashed } from 'lucide-vue-next';
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: HiddenElement
|
||||
})
|
||||
|
||||
let emit = defineEmits(['update:modelValue']);
|
||||
|
||||
const theModel = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (value) => emit('update:modelValue', value),
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex gap-2 flex-row">
|
||||
<SquareDashed />
|
||||
<label>{{theModel?.id}}</label>
|
||||
</div>
|
||||
</template>
|
||||
@ -2,6 +2,7 @@
|
||||
import InputElement from '@/model/InputElement';
|
||||
import { computed } from 'vue';
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { SquarePen } from 'lucide-vue-next';
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: InputElement
|
||||
@ -18,8 +19,9 @@ const theModel = computed({
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="">
|
||||
<label>{{theModel?.name}}</label>
|
||||
<Input :placeholder="theModel?.placeholder" :value="theModel?.value" :name="theModel?.name" :id="theModel?.id" :required="theModel?.required"/>
|
||||
<div class="flex gap-2 flex-row items-center">
|
||||
<SquarePen class="flex-none" />
|
||||
<label class="w-60 flex-inital">{{theModel?.name}}</label>
|
||||
<Input :placeholder="theModel?.placeholder" :value="theModel?.default" :name="theModel?.name" :id="theModel?.id" :required="theModel?.required"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -0,0 +1,86 @@
|
||||
<script lang="ts" setup>
|
||||
import Row from '@/model/Row';
|
||||
import Column from '@/model/Column';
|
||||
import { ref, computed } from 'vue';
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { SquareDashed } from 'lucide-vue-next';
|
||||
import EmptyElementForm from './EmptyElementForm.vue'
|
||||
import { RenderElements } from './../renderelements'
|
||||
import { useElementStore } from '@/stores/Items'
|
||||
import Parser from '@/lib/parser'
|
||||
import { CirclePlus } from 'lucide-vue-next';
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: Row
|
||||
})
|
||||
|
||||
let emit = defineEmits(['update:modelValue']);
|
||||
const dragUuid = ref("");
|
||||
const store = useElementStore()
|
||||
|
||||
const theModel = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (value) => emit('update:modelValue', value),
|
||||
});
|
||||
|
||||
const onDrop = (event: DragEvent, targetUuid: string, column: Column) => {
|
||||
dragUuid.value = ""
|
||||
if(event.dataTransfer?.getData('mode') == "sort") {
|
||||
let item = store.cutItem(store.getSourceDragUuid)
|
||||
column.items.push(item)
|
||||
store.setDragMode("")
|
||||
event.stopImmediatePropagation()
|
||||
}
|
||||
|
||||
if(store.getDragMode == "insert") {
|
||||
const itemId = Number(event.dataTransfer?.getData('itemId'));
|
||||
|
||||
column.items.push(Parser.getModelForType(itemId))
|
||||
store.setDragMode("")
|
||||
event.stopImmediatePropagation()
|
||||
}
|
||||
}
|
||||
|
||||
const dragEnter = (event: DragEvent, uuid: string) => {
|
||||
dragUuid.value = uuid
|
||||
event.stopImmediatePropagation()
|
||||
if(store.getDragMode == "sort" && uuid != store.getSourceDragUuid) {
|
||||
event.stopImmediatePropagation()
|
||||
}
|
||||
}
|
||||
|
||||
const dragLeaveEmpty = (event: DragEvent, uuid: string) => {
|
||||
dragUuid.value = ""
|
||||
event.stopImmediatePropagation()
|
||||
}
|
||||
|
||||
|
||||
const dragEnterEmpty = (event: DragEvent, uuid: string) => {
|
||||
dragUuid.value = uuid
|
||||
event.stopImmediatePropagation()
|
||||
if(store.getDragMode == "sort" && uuid != store.getSourceDragUuid) {
|
||||
event.stopImmediatePropagation()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex gap-2 flex-col">
|
||||
<div class="w-full flex flex-row gap-1" v-if="theModel!.columns.length > 0">
|
||||
<div class="grow border p-1 bg-white" v-for="col in theModel!.columns">
|
||||
<div class="h-8 group items-center content-justify w-full mb-2" v-if="col.items.length == 0" @drop="onDrop($event, theModel!.uuid, col)" @dragleave="dragLeaveEmpty($event, col.uuid)" @dragenter="dragEnterEmpty($event, col.uuid)"> <div class="inline-flex items-center justify-center w-full pointer-events-none">
|
||||
<hr class="w-64 h-px my-2 bg-gray-200 border-0 dark:bg-gray-700 transition duration-200 pointer-events-none" :class="{ 'bg-orange-500': dragUuid == col.uuid }" >
|
||||
<span class="absolute px-3 font-medium text-gray-900 bg-white dark:text-white dark:bg-gray-900 pointer-events-none"><CirclePlus :class="{ 'text-orange-500': dragUuid == col.uuid }" class="transition duration-200 pointer-events-none" /></span>
|
||||
</div>
|
||||
</div>
|
||||
<RenderElements
|
||||
@drop="onDrop($event, theModel!.uuid, col)"
|
||||
v-if="col.items.length > 0"
|
||||
v-bind:items="col.items"/>
|
||||
</div>
|
||||
</div>
|
||||
<EmptyElementForm
|
||||
v-if="theModel!.columns.length == 0"/>
|
||||
</div>
|
||||
</template>
|
||||
@ -0,0 +1,48 @@
|
||||
<script lang="ts" setup>
|
||||
import SelectElement from '@/model/SelectElement'
|
||||
import { computed } from 'vue'
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectGroup,
|
||||
SelectItem,
|
||||
SelectLabel,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from '@/components/ui/select'
|
||||
import { SquareParking, SquareChevronDown, SquareDashed } from 'lucide-vue-next';
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: SelectElement
|
||||
})
|
||||
|
||||
let emit = defineEmits(['update:modelValue'])
|
||||
|
||||
const theModel = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (value) => emit('update:modelValue', value),
|
||||
})
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex gap-2 flex-row items-center">
|
||||
<SquareChevronDown class="flex-none" />
|
||||
<label class="w-60 flex-inital">{{theModel?.name}}</label>
|
||||
<div class="w-full">
|
||||
<Select :modelValue="theModel?.default">
|
||||
<SelectTrigger>
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<SelectItem v-for="option in theModel?.options" :key="option.uuid" :value="option.id">
|
||||
{{option.name}}
|
||||
</SelectItem>
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -0,0 +1,26 @@
|
||||
<script lang="ts" setup>
|
||||
import TextElement from '@/model/TextElement';
|
||||
import { computed } from 'vue';
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { SquareParking } from 'lucide-vue-next';
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: TextElement
|
||||
})
|
||||
|
||||
let emit = defineEmits(['update:modelValue']);
|
||||
|
||||
const theModel = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (value) => emit('update:modelValue', value),
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex gap-2 flex-row">
|
||||
<SquareParking />
|
||||
<p>{{theModel?.default}}</p>
|
||||
</div>
|
||||
</template>
|
||||
@ -0,0 +1,27 @@
|
||||
<script lang="ts" setup>
|
||||
import TextareaElement from '@/model/TextareaElement';
|
||||
import { computed } from 'vue';
|
||||
import { Textarea } from '@/components/ui/textarea'
|
||||
import { SquareMenu } from 'lucide-vue-next';
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: TextareaElement
|
||||
})
|
||||
|
||||
let emit = defineEmits(['update:modelValue']);
|
||||
|
||||
const theModel = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (value) => emit('update:modelValue', value),
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex gap-2 flex-row">
|
||||
<SquareMenu class="flex-none" />
|
||||
<label class="w-60 flex-inital">{{theModel?.name}}</label>
|
||||
<Textarea :value="theModel?.default" :name="theModel?.name" :id="theModel?.id"/>
|
||||
</div>
|
||||
</template>
|
||||
@ -1,22 +1,47 @@
|
||||
<script setup lang="ts">
|
||||
import { useElementStore } from '@/stores/Items'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { SquareParking, SquareDot, SquareMenu, SquarePen, SquareChevronDown, SquareDashed } from 'lucide-vue-next';
|
||||
|
||||
const store = useElementStore()
|
||||
|
||||
function startDrag(event: DragEvent, item: string) {
|
||||
event.dataTransfer!.dropEffect = 'move';
|
||||
event.dataTransfer!.effectAllowed = 'move';
|
||||
event.dataTransfer?.setData('itemId', item);
|
||||
event.dataTransfer.dropEffect = 'move';
|
||||
event.dataTransfer.effectAllowed = 'move';
|
||||
event.dataTransfer.setData('itemId', item);
|
||||
store.setDragMode("insert")
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col m-2">
|
||||
<div id="input" class="w-full" draggable="true" @dragstart="startDrag($event, '2')" @dragenter.prevent @dragover.prevent>
|
||||
<Input />
|
||||
<div class="flex flex-col p-3 gap-3 overflow-auto">
|
||||
<div id="headline" class="border-1 p-2 w-full flex flex-row gap-2" draggable="true" @dragstart="startDrag($event, '6')" @dragenter.prevent @dragover.prevent>
|
||||
<SquareDot />
|
||||
<span>Headline</span>
|
||||
</div>
|
||||
<div id="text" class="border-1 p-2 w-full flex flex-row gap-2" draggable="true" @dragstart="startDrag($event, '4')" @dragenter.prevent @dragover.prevent>
|
||||
<SquareParking />
|
||||
<span>Text</span>
|
||||
</div>
|
||||
<div id="textarea" class="border-1 p-2 w-full flex flex-row gap-2" draggable="true" @dragstart="startDrag($event, '5')" @dragenter.prevent @dragover.prevent>
|
||||
<SquareMenu />
|
||||
<span>Textarea</span>
|
||||
</div>
|
||||
<div id="input" class="border-1 p-2 w-full flex flex-row gap-2" draggable="true" @dragstart="startDrag($event, '2')" @dragenter.prevent @dragover.prevent>
|
||||
<SquarePen />
|
||||
<span>Input</span>
|
||||
</div>
|
||||
<div id="select" class="border-1 p-2 w-full flex flex-row gap-2" draggable="true" @dragstart="startDrag($event, '3')" @dragenter.prevent @dragover.prevent>
|
||||
<SquareChevronDown />
|
||||
<span>Select</span>
|
||||
</div>
|
||||
<div id="hidden" class="border-1 p-2 w-full flex flex-row gap-2" draggable="true" @dragstart="startDrag($event, '1')" @dragenter.prevent @dragover.prevent>
|
||||
<SquareDashed />
|
||||
<span>Hidden</span>
|
||||
</div>
|
||||
<div id="row" class="border-1 p-2 w-full flex flex-row gap-2" draggable="true" @dragstart="startDrag($event, '7')" @dragenter.prevent @dragover.prevent>
|
||||
<SquareDashed />
|
||||
<span>Row</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -8,7 +8,6 @@ const store = useElementStore()
|
||||
function onDrop(event: DragEvent) {
|
||||
if(store.dragMode == "insert") {
|
||||
const itemType = Number(event.dataTransfer?.getData('itemId'));
|
||||
|
||||
store.addElement(Parser.getModelForType(itemType))
|
||||
store.clearSelection()
|
||||
}
|
||||
@ -16,7 +15,7 @@ function onDrop(event: DragEvent) {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="border m-4 p-4 rounded-xl w-full h-full bg-[radial-gradient(#e5e7eb_1px,transparent_1px)] [background-size:16px_16px]" @drop="onDrop($event)" @dragover.prevent>
|
||||
<div class="border m-1 p-4 rounded-xl w-full h-full shadow bg-white" @drop="onDrop($event)" @dragover.prevent>
|
||||
<RenderElements v-bind:items="store.getItems" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -0,0 +1,63 @@
|
||||
<script lang="ts" setup>
|
||||
import HeadlineElement from '@/model/HeadlineElement';
|
||||
import { computed } from 'vue';
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Checkbox } from '@/components/ui/checkbox'
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectGroup,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from '@/components/ui/select'
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: HeadlineElement
|
||||
})
|
||||
|
||||
let emit = defineEmits(['update:modelValue']);
|
||||
|
||||
const theModel = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (value) => emit('update:modelValue', value),
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<label>ID</label>
|
||||
<Input v-model="theModel!.id" />
|
||||
<label>Default</label>
|
||||
<Input v-model="theModel!.default"/>
|
||||
<label>Name</label>
|
||||
<Input v-model="theModel!.name"/>
|
||||
<label>Variant</label>
|
||||
<Select v-model="theModel!.variant">
|
||||
<SelectTrigger>
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<SelectItem value="1">
|
||||
Headline 1
|
||||
</SelectItem>
|
||||
<SelectItem value="2">
|
||||
Headline 2
|
||||
</SelectItem>
|
||||
<SelectItem value="3">
|
||||
Headline 3
|
||||
</SelectItem>
|
||||
<SelectItem value="4">
|
||||
Headline 4
|
||||
</SelectItem>
|
||||
<SelectItem value="5">
|
||||
Headline 5
|
||||
</SelectItem>
|
||||
<SelectItem value="6">
|
||||
Headline 6
|
||||
</SelectItem>
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</template>
|
||||
@ -0,0 +1,27 @@
|
||||
<script lang="ts" setup>
|
||||
import HiddenElement from '@/model/HiddenElement';
|
||||
import { computed } from 'vue';
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Checkbox } from '@/components/ui/checkbox'
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: HiddenElement
|
||||
})
|
||||
|
||||
let emit = defineEmits(['update:modelValue']);
|
||||
|
||||
const theModel = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (value) => emit('update:modelValue', value),
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<label>ID</label>
|
||||
<Input v-model="theModel!.id" />
|
||||
<label>Default</label>
|
||||
<Input v-model="theModel!.default"/>
|
||||
<label>Name</label>
|
||||
<Input v-model="theModel!.name"/>
|
||||
</template>
|
||||
@ -22,8 +22,8 @@ const theModel = computed({
|
||||
<Input v-model="theModel!.id" />
|
||||
<label>Placeholder</label>
|
||||
<Input v-model="theModel!.placeholder"/>
|
||||
<label>Value</label>
|
||||
<Input v-model="theModel!.value"/>
|
||||
<label>Default</label>
|
||||
<Input v-model="theModel!.default"/>
|
||||
<label>Name</label>
|
||||
<Input v-model="theModel!.name"/>
|
||||
<Checkbox v-model="theModel!.required"/>
|
||||
|
||||
@ -0,0 +1,29 @@
|
||||
<script lang="ts" setup>
|
||||
import Option from '@/model/select/Option';
|
||||
import { computed } from 'vue';
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Dependency } from '../elementdependency'
|
||||
import { default as DepModel } from '../../../model/Dependency.ts'
|
||||
|
||||
const props = defineProps({
|
||||
option: Option,
|
||||
})
|
||||
|
||||
function addDependency(option) {
|
||||
option.addDependency(new DepModel());
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-row gap-1">
|
||||
<label>ID</label>
|
||||
<Input v-model="option.id" />
|
||||
<label>Name</label>
|
||||
<Input v-model="option.name"/>
|
||||
<Button v-on:click="addDependency(option)">Add Dependency</Button>
|
||||
</div>
|
||||
<Dependency :dependencys="option.dependencys" />
|
||||
</template>
|
||||
@ -0,0 +1,27 @@
|
||||
<script lang="ts" setup>
|
||||
import Row from '@/model/Row'
|
||||
import Column from '@/model/Column'
|
||||
import { computed } from 'vue'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Button } from '@/components/ui/button'
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: Row
|
||||
})
|
||||
|
||||
let emit = defineEmits(['update:modelValue'])
|
||||
|
||||
const theModel = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (value) => emit('update:modelValue', value),
|
||||
})
|
||||
|
||||
function addColumn(row: Row) {
|
||||
row.addColumn(new Column())
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Button v-on:click="addColumn(theModel)">add Column</Button>
|
||||
</template>
|
||||
@ -0,0 +1,97 @@
|
||||
<script lang="ts" setup>
|
||||
import SelectElement from '@/model/SelectElement';
|
||||
import Option from '@/model/select/Option';
|
||||
import { computed } from 'vue';
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Checkbox } from '@/components/ui/checkbox'
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectGroup,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from '@/components/ui/select'
|
||||
import OptionElement from './OptionElement.vue'
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogClose,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from '@/components/ui/dialog'
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: SelectElement
|
||||
})
|
||||
|
||||
let emit = defineEmits(['update:modelValue']);
|
||||
|
||||
const theModel = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (value) => emit('update:modelValue', value),
|
||||
});
|
||||
|
||||
function addOption(obj) {
|
||||
obj.addOption(new Option(String(obj.options.length + 1)));
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<label>ID</label>
|
||||
<Input v-model="theModel!.id" />
|
||||
<label>Default</label>
|
||||
<Input v-model="theModel!.default"/>
|
||||
<label>Name</label>
|
||||
<Input v-model="theModel!.name"/>
|
||||
<label>Mode</label>
|
||||
<Select v-model="theModel!.mode">
|
||||
<SelectTrigger>
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<SelectItem value="normal">
|
||||
Normal
|
||||
</SelectItem>
|
||||
<SelectItem value="paperdb">
|
||||
PaperDB
|
||||
</SelectItem>
|
||||
<SelectItem value="colordb">
|
||||
ColorDB
|
||||
</SelectItem>
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<label>Container</label>
|
||||
<Input v-model="theModel!.container"/>
|
||||
<Dialog >
|
||||
<DialogTrigger>
|
||||
<Button class="mt-2">Edit Options</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent class="min-w-full grid-rows-[auto_minmax(0,1fr)_auto] p-4 max-h-[90dvh]">
|
||||
<DialogHeader>
|
||||
<DialogTitle>Edit Options</DialogTitle>
|
||||
<DialogDescription>
|
||||
<Button v-on:click="addOption(theModel)">Add Option</Button>
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<div class="w-full grid overflow-y-auto px-6">
|
||||
<div class="d-flex flex-wrap p-2 relative" v-for="opt in theModel.options" :key="opt.uuid">
|
||||
<OptionElement :option="opt"/>
|
||||
</div>
|
||||
</div>
|
||||
<DialogFooter>
|
||||
<DialogClose as-child>
|
||||
<Button type="button" variant="secondary">
|
||||
Close
|
||||
</Button>
|
||||
</DialogClose>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</template>
|
||||
@ -0,0 +1,27 @@
|
||||
<script lang="ts" setup>
|
||||
import TextElement from '@/model/TextElement';
|
||||
import { computed } from 'vue';
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Checkbox } from '@/components/ui/checkbox'
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: TextElement
|
||||
})
|
||||
|
||||
let emit = defineEmits(['update:modelValue']);
|
||||
|
||||
const theModel = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (value) => emit('update:modelValue', value),
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<label>ID</label>
|
||||
<Input v-model="theModel!.id" />
|
||||
<label>Default</label>
|
||||
<Input v-model="theModel!.default"/>
|
||||
<label>Name</label>
|
||||
<Input v-model="theModel!.name"/>
|
||||
</template>
|
||||
@ -0,0 +1,28 @@
|
||||
<script lang="ts" setup>
|
||||
import TextareaElement from '@/model/TextareaElement';
|
||||
import { computed } from 'vue';
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Textarea } from '@/components/ui/textarea'
|
||||
import { Checkbox } from '@/components/ui/checkbox'
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: TextareaElement
|
||||
})
|
||||
|
||||
let emit = defineEmits(['update:modelValue']);
|
||||
|
||||
const theModel = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (value) => emit('update:modelValue', value),
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<label>ID</label>
|
||||
<Input v-model="theModel!.id" />
|
||||
<label>Name</label>
|
||||
<Input v-model="theModel!.name"/>
|
||||
<label>Default</label>
|
||||
<Textarea v-model="theModel!.default"/>
|
||||
</template>
|
||||
@ -1,11 +1,24 @@
|
||||
<script lang="ts" setup>
|
||||
import BaseElement from '@/model/BaseElement';
|
||||
import InputElementForm from '../elements/InputElementForm.vue'
|
||||
import InputElement from '@/model/InputElement';
|
||||
import { useElementStore } from '@/stores/Items';
|
||||
import type { PropType } from 'vue';
|
||||
import HiddenElementForm from '../elements/HiddenElementForm.vue'
|
||||
import HeadlineElementForm from '../elements/HeadlineElementForm.vue'
|
||||
import TextElementForm from '../elements/TextElementForm.vue'
|
||||
import TextareaElementForm from '../elements/TextareaElementForm.vue'
|
||||
import SelectElementForm from '../elements/SelectElementForm.vue'
|
||||
import RowElementForm from '../elements/RowElementForm.vue'
|
||||
import InputElement from '@/model/InputElement'
|
||||
import HiddenElement from '@/model/HiddenElement'
|
||||
import TextElement from '@/model/TextElement'
|
||||
import TextareaElement from '@/model/TextareaElement'
|
||||
import HeadlineElement from '@/model/HeadlineElement'
|
||||
import Row from '@/model/Row'
|
||||
import SelectElement from '@/model/SelectElement'
|
||||
import { useElementStore } from '@/stores/Items'
|
||||
import type { PropType } from 'vue'
|
||||
import Parser from '@/lib/parser'
|
||||
import { Settings, Trash, Move } from 'lucide-vue-next';
|
||||
import { Settings, Trash, Move, CirclePlus, Waypoints } from 'lucide-vue-next';
|
||||
import { ref } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
items: Array as PropType<BaseElement[]>
|
||||
@ -13,38 +26,38 @@ const props = defineProps({
|
||||
|
||||
const store = useElementStore()
|
||||
|
||||
const elementFocus = (event: Event, item: BaseElement) => {
|
||||
store.changeFocus(item.uuid)
|
||||
store.setShowProperties(true)
|
||||
store.setActiveItem(item)
|
||||
event.stopImmediatePropagation()
|
||||
}
|
||||
const dragUuid = ref("");
|
||||
|
||||
const startDrag = (event: DragEvent, uuid: string) => {
|
||||
event.dataTransfer!.dropEffect = 'move';
|
||||
event.dataTransfer!.effectAllowed = 'move';
|
||||
event.dataTransfer?.setData('mode', "sort");
|
||||
event.dataTransfer!.dropEffect = 'move'
|
||||
event.dataTransfer!.effectAllowed = 'move'
|
||||
event.dataTransfer?.setData('mode', "sort")
|
||||
store.setDragMode("sort")
|
||||
store.setSourceDragUuid(uuid)
|
||||
event.stopImmediatePropagation()
|
||||
}
|
||||
|
||||
const dragLeave = (event: DragEvent, uuid: string) => {
|
||||
dragUuid.value = ""
|
||||
event.stopImmediatePropagation()
|
||||
}
|
||||
|
||||
const dragEnter = (event: DragEvent, uuid: string) => {
|
||||
dragUuid.value = uuid
|
||||
if(store.getDragMode == "sort" && uuid != store.getSourceDragUuid) {
|
||||
store.moveItemBefore(store.getSourceDragUuid, uuid)
|
||||
event.stopImmediatePropagation()
|
||||
}
|
||||
}
|
||||
|
||||
const stopDrag = (event: DragEvent, uuid: string) => {
|
||||
dragUuid.value = ""
|
||||
if(event.dataTransfer?.getData('mode') == "sort") {
|
||||
store.moveItemBefore(store.getSourceDragUuid, uuid)
|
||||
store.setDragMode("")
|
||||
event.stopImmediatePropagation()
|
||||
}
|
||||
if(store.dragMode == "insert") {
|
||||
const itemType = Number(event.dataTransfer?.getData('itemId'));
|
||||
|
||||
const itemType = Number(event.dataTransfer?.getData('itemId'))
|
||||
store.addElementAfter(Parser.getModelForType(itemType), uuid)
|
||||
store.clearSelection()
|
||||
event.stopImmediatePropagation()
|
||||
@ -59,27 +72,62 @@ const editElementProperties = (item: BaseElement) => {
|
||||
store.setShowProperties(true)
|
||||
store.setActiveItem(item)
|
||||
}
|
||||
const editElementDependency = (item: BaseElement) => {
|
||||
store.setShowDependency(true)
|
||||
store.setActiveItem(item)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="d-flex bg-slate-50 flex-wrap p-2 relative" @dragenter="dragEnter($event, item.uuid)" @drop="stopDrag($event, item.uuid)" v-on:click="elementFocus($event, item)" v-bind:class="{ 'border border-rose-500': item.isFocused === true }" v-for="item in items" :key="item.uuid">
|
||||
|
||||
<InputElementForm
|
||||
v-if="item.type === 2"
|
||||
v-model="item as InputElement"
|
||||
/>
|
||||
|
||||
|
||||
<div class="absolute size-14 -right-15 top-0 flex-col" v-bind:class="{ invisible: item.isFocused === false }">
|
||||
<div @dragstart="startDrag($event, item.uuid)" draggable="true" class="size-10 flex items-center justify-center m-1 bg-gray-500 rounded-full text-white border p-1 cursor-pointer">
|
||||
<Move />
|
||||
<div class="overflow-auto h-full">
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="d-flex flex flex-col relative items-center " v-for="item in items" v-if="items.length > 0" :key="item.uuid">
|
||||
<div class="h-8 group w-full mb-2" @dragleave.self="dragLeave($event, item.uuid)" @dragenter.self="dragEnter($event, item.uuid)" @drop="stopDrag($event, item.uuid)">
|
||||
<div class="inline-flex items-center justify-center w-full pointer-events-none">
|
||||
<hr class="w-64 h-px my-2 bg-gray-200 border-0 dark:bg-gray-700 transition duration-200 pointer-events-none" :class="{ 'bg-orange-500': dragUuid == item.uuid }" >
|
||||
<span class="absolute px-3 font-medium text-gray-900 -translate-x-1/2 bg-white left-1/2 dark:text-white dark:bg-gray-900 pointer-events-none"><CirclePlus :class="{ 'text-orange-500': dragUuid == item.uuid }" class="transition duration-200 pointer-events-none" /></span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-on:click="editElementProperties(item)" class="size-10 flex items-center justify-center m-1 bg-gray-500 rounded-full text-white border p-1 cursor-pointer">
|
||||
<Settings />
|
||||
</div>
|
||||
<div v-on:click="deleteItem(item)" class="size-10 flex items-center justify-center m-1 bg-red-500 rounded-full text-white border p-1 cursor-pointer">
|
||||
<Trash />
|
||||
<div @dragstart="startDrag($event, item.uuid)" draggable="true" class="w-full flex flex-row border-1 border-slate-200 border-dashed p-2 hover:bg-gray-100 transition duration-500" v-bind:class="{ ' bg-slate-50': item.isFocused === true }">
|
||||
<div class="m-2 cursor-pointer">
|
||||
<Move />
|
||||
</div>
|
||||
|
||||
<div class="grow content-center items-center">
|
||||
<InputElementForm
|
||||
v-if="item.type === 2"
|
||||
v-model="item as InputElement"
|
||||
/>
|
||||
<SelectElementForm
|
||||
v-if="item.type === 3"
|
||||
v-model="item as SelectElement"
|
||||
/>
|
||||
<TextElementForm
|
||||
v-if="item.type === 4"
|
||||
v-model="item as TextElement"
|
||||
/>
|
||||
<TextareaElementForm
|
||||
v-if="item.type === 5"
|
||||
v-model="item as TextareaElement"
|
||||
/>
|
||||
<HeadlineElementForm
|
||||
v-if="item.type === 6"
|
||||
v-model="item as HeadlineElement"
|
||||
/>
|
||||
<RowElementForm
|
||||
v-if="item.type === 7"
|
||||
v-model="item as Row"
|
||||
/>
|
||||
</div>
|
||||
<div v-on:click="editElementDependency(item)" class="m-2 cursor-pointer">
|
||||
<Waypoints />
|
||||
</div>
|
||||
<div v-on:click="editElementProperties(item)" class="m-2 cursor-pointer">
|
||||
<Settings />
|
||||
</div>
|
||||
<div v-on:click="deleteItem(item)" class="text-red-500 m-2 cursor-pointer">
|
||||
<Trash />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -29,7 +29,7 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||
v-bind="forwarded"
|
||||
:class="
|
||||
cn(
|
||||
'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg',
|
||||
'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200',
|
||||
props.class,
|
||||
)"
|
||||
>
|
||||
|
||||
@ -0,0 +1,17 @@
|
||||
<script setup lang="ts">
|
||||
import { DialogRoot, type DialogRootEmits, type DialogRootProps, useForwardPropsEmits } from 'reka-ui'
|
||||
|
||||
const props = defineProps<DialogRootProps>()
|
||||
const emits = defineEmits<DialogRootEmits>()
|
||||
|
||||
const forwarded = useForwardPropsEmits(props, emits)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DialogRoot
|
||||
data-slot="sheet"
|
||||
v-bind="forwarded"
|
||||
>
|
||||
<slot />
|
||||
</DialogRoot>
|
||||
</template>
|
||||
@ -0,0 +1,14 @@
|
||||
<script setup lang="ts">
|
||||
import { DialogClose, type DialogCloseProps } from 'reka-ui'
|
||||
|
||||
const props = defineProps<DialogCloseProps>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DialogClose
|
||||
data-slot="sheet-close"
|
||||
v-bind="props"
|
||||
>
|
||||
<slot />
|
||||
</DialogClose>
|
||||
</template>
|
||||
@ -0,0 +1,63 @@
|
||||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { reactiveOmit } from '@vueuse/core'
|
||||
import { X } from 'lucide-vue-next'
|
||||
import {
|
||||
DialogClose,
|
||||
DialogContent,
|
||||
type DialogContentEmits,
|
||||
type DialogContentProps,
|
||||
DialogPortal,
|
||||
useForwardPropsEmits,
|
||||
} from 'reka-ui'
|
||||
import { cn } from '@/lib/utils'
|
||||
import SheetOverlay from './SheetOverlay.vue'
|
||||
|
||||
interface SheetContentProps extends DialogContentProps {
|
||||
class?: HTMLAttributes['class']
|
||||
side?: 'top' | 'right' | 'bottom' | 'left'
|
||||
}
|
||||
|
||||
defineOptions({
|
||||
inheritAttrs: false,
|
||||
})
|
||||
|
||||
const props = withDefaults(defineProps<SheetContentProps>(), {
|
||||
side: 'right',
|
||||
})
|
||||
const emits = defineEmits<DialogContentEmits>()
|
||||
|
||||
const delegatedProps = reactiveOmit(props, 'class', 'side')
|
||||
|
||||
const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DialogPortal>
|
||||
<SheetOverlay />
|
||||
<DialogContent
|
||||
data-slot="sheet-content"
|
||||
:class="cn(
|
||||
'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col gap-4 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500',
|
||||
side === 'right'
|
||||
&& 'data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm',
|
||||
side === 'left'
|
||||
&& 'data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm',
|
||||
side === 'top'
|
||||
&& 'data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto border-b',
|
||||
side === 'bottom'
|
||||
&& 'data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inset-x-0 bottom-0 h-auto border-t',
|
||||
props.class)"
|
||||
v-bind="{ ...forwarded, ...$attrs }"
|
||||
>
|
||||
<slot />
|
||||
|
||||
<DialogClose
|
||||
class="ring-offset-background focus:ring-ring data-[state=open]:bg-secondary absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none"
|
||||
>
|
||||
<X class="size-4" />
|
||||
<span class="sr-only">Close</span>
|
||||
</DialogClose>
|
||||
</DialogContent>
|
||||
</DialogPortal>
|
||||
</template>
|
||||
@ -0,0 +1,20 @@
|
||||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { reactiveOmit } from '@vueuse/core'
|
||||
import { DialogDescription, type DialogDescriptionProps } from 'reka-ui'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<DialogDescriptionProps & { class?: HTMLAttributes['class'] }>()
|
||||
|
||||
const delegatedProps = reactiveOmit(props, 'class')
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DialogDescription
|
||||
data-slot="sheet-description"
|
||||
:class="cn('text-muted-foreground text-sm', props.class)"
|
||||
v-bind="delegatedProps"
|
||||
>
|
||||
<slot />
|
||||
</DialogDescription>
|
||||
</template>
|
||||
@ -0,0 +1,16 @@
|
||||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<{ class?: HTMLAttributes['class'] }>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
data-slot="sheet-footer"
|
||||
:class="cn('mt-auto flex flex-col gap-2 p-4', props.class)
|
||||
"
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
@ -0,0 +1,15 @@
|
||||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<{ class?: HTMLAttributes['class'] }>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
data-slot="sheet-header"
|
||||
:class="cn('flex flex-col gap-1.5 p-4', props.class)"
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
@ -0,0 +1,20 @@
|
||||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { reactiveOmit } from '@vueuse/core'
|
||||
import { DialogOverlay, type DialogOverlayProps } from 'reka-ui'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<DialogOverlayProps & { class?: HTMLAttributes['class'] }>()
|
||||
|
||||
const delegatedProps = reactiveOmit(props, 'class')
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DialogOverlay
|
||||
data-slot="sheet-overlay"
|
||||
:class="cn('data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/80', props.class)"
|
||||
v-bind="delegatedProps"
|
||||
>
|
||||
<slot />
|
||||
</DialogOverlay>
|
||||
</template>
|
||||
@ -0,0 +1,20 @@
|
||||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { reactiveOmit } from '@vueuse/core'
|
||||
import { DialogTitle, type DialogTitleProps } from 'reka-ui'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<DialogTitleProps & { class?: HTMLAttributes['class'] }>()
|
||||
|
||||
const delegatedProps = reactiveOmit(props, 'class')
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DialogTitle
|
||||
data-slot="sheet-title"
|
||||
:class="cn('text-foreground font-semibold', props.class)"
|
||||
v-bind="delegatedProps"
|
||||
>
|
||||
<slot />
|
||||
</DialogTitle>
|
||||
</template>
|
||||
@ -0,0 +1,14 @@
|
||||
<script setup lang="ts">
|
||||
import { DialogTrigger, type DialogTriggerProps } from 'reka-ui'
|
||||
|
||||
const props = defineProps<DialogTriggerProps>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DialogTrigger
|
||||
data-slot="sheet-trigger"
|
||||
v-bind="props"
|
||||
>
|
||||
<slot />
|
||||
</DialogTrigger>
|
||||
</template>
|
||||
@ -0,0 +1,8 @@
|
||||
export { default as Sheet } from './Sheet.vue'
|
||||
export { default as SheetClose } from './SheetClose.vue'
|
||||
export { default as SheetContent } from './SheetContent.vue'
|
||||
export { default as SheetDescription } from './SheetDescription.vue'
|
||||
export { default as SheetFooter } from './SheetFooter.vue'
|
||||
export { default as SheetHeader } from './SheetHeader.vue'
|
||||
export { default as SheetTitle } from './SheetTitle.vue'
|
||||
export { default as SheetTrigger } from './SheetTrigger.vue'
|
||||
@ -1,12 +1,33 @@
|
||||
import type BaseElement from "../model/BaseElement"
|
||||
import InputElement from "../model/InputElement"
|
||||
import Row from "../model/Row"
|
||||
import Column from "../model/Column"
|
||||
import HiddenElement from "../model/HiddenElement"
|
||||
import SelectElement from "../model/SelectElement"
|
||||
import TextElement from "../model/TextElement"
|
||||
import TextareaElement from "../model/TextareaElement"
|
||||
import HeadlineElement from "../model/HeadlineElement"
|
||||
|
||||
export default class Parser {
|
||||
|
||||
static getModelForType(type: Number) : BaseElement {
|
||||
switch(type) {
|
||||
case 8:
|
||||
return new Column
|
||||
case 7:
|
||||
return new Row
|
||||
case 6:
|
||||
return new HeadlineElement
|
||||
case 5:
|
||||
return new TextareaElement
|
||||
case 4:
|
||||
return new TextElement
|
||||
case 3:
|
||||
return new SelectElement
|
||||
case 2:
|
||||
return new InputElement
|
||||
case 1:
|
||||
return new HiddenElement
|
||||
default:
|
||||
return new InputElement
|
||||
}
|
||||
|
||||
@ -67,7 +67,10 @@ export default class BaseElement {
|
||||
return null
|
||||
}
|
||||
|
||||
deleteItem(item: BaseElement) {
|
||||
getItem(existingUuid: string) {
|
||||
return null
|
||||
}
|
||||
|
||||
deleteItem(item: BaseElement) {
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,77 @@
|
||||
import BaseElement from "./BaseElement";
|
||||
|
||||
export default class Column extends BaseElement {
|
||||
items: BaseElement[] = []
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
this.type = 8
|
||||
}
|
||||
|
||||
addItem(item: BaseElement) {
|
||||
this.items.push(item)
|
||||
}
|
||||
|
||||
public toJSON() {
|
||||
return Object.assign(
|
||||
super.toJSON(),
|
||||
{
|
||||
'items': this.items.reduce((result, item) => {
|
||||
result.push(item.toJSON())
|
||||
return result
|
||||
}, [])
|
||||
})
|
||||
}
|
||||
|
||||
fromJSON(obj) {
|
||||
super.fromJSON(obj)
|
||||
obj.columns.map((d) => {
|
||||
const column = new Column()
|
||||
column.fromJSON(d)
|
||||
this.columns.push(column)
|
||||
})
|
||||
}
|
||||
|
||||
getItem(existingUuid: string) {
|
||||
let item: BaseElement|null = null;
|
||||
this.items.some((element,indexArray) => {
|
||||
if(element.uuid === existingUuid) {
|
||||
return element
|
||||
}
|
||||
if(item === null) {
|
||||
return element.getItem(existingUuid)
|
||||
}
|
||||
});
|
||||
return item
|
||||
}
|
||||
|
||||
cutItem(existingUuid: string) {
|
||||
let item: BaseElement|null = null;
|
||||
this.items.forEach((element,indexArray) => {
|
||||
if(element.uuid === existingUuid) {
|
||||
item = this.items.splice(indexArray, 1)[0]
|
||||
return true
|
||||
}
|
||||
if(item === null) {
|
||||
item = element.cutItem(existingUuid)
|
||||
}
|
||||
});
|
||||
return item
|
||||
}
|
||||
|
||||
insertItem(item: BaseElement, targetUuid: string): boolean {
|
||||
let inserted = false;
|
||||
for (let i = 0; i < this.items.length; ++i) {
|
||||
if(this.items[i].uuid === targetUuid) {
|
||||
this.items.splice(i, 0, item);
|
||||
inserted = true;
|
||||
return false
|
||||
}
|
||||
if(!inserted) {
|
||||
this.items[i].insertItem(item, targetUuid)
|
||||
}
|
||||
}
|
||||
|
||||
return inserted
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
import BaseElement from "./BaseElement";
|
||||
|
||||
export default class HeadlineElement extends BaseElement {
|
||||
default: string = ""
|
||||
variant: string = "1"
|
||||
name: string = ""
|
||||
xmlType: string = "text"
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.type = 6
|
||||
}
|
||||
|
||||
public toJSON() {
|
||||
return Object.assign(
|
||||
super.toJSON(),
|
||||
{
|
||||
'default': this.default,
|
||||
'name': this.name,
|
||||
'variant': this.variant,
|
||||
})
|
||||
}
|
||||
|
||||
fromJSON(obj) {
|
||||
super.fromJSON(obj)
|
||||
this.name = obj.name
|
||||
this.default = obj.default
|
||||
this.variant = obj.variant
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
import BaseElement from "./BaseElement";
|
||||
|
||||
export default class HiddenElement extends BaseElement {
|
||||
default: string = ""
|
||||
name: string = ""
|
||||
xmlType: string = "hidden"
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.type = 1
|
||||
}
|
||||
|
||||
public toJSON() {
|
||||
return Object.assign(
|
||||
super.toJSON(),
|
||||
{
|
||||
'default': this.default,
|
||||
'name': this.name,
|
||||
})
|
||||
}
|
||||
|
||||
fromJSON(obj) {
|
||||
super.fromJSON(obj)
|
||||
this.name = obj.name
|
||||
this.default = obj.default
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
import BaseElement from "./BaseElement";
|
||||
|
||||
export default class InputElement extends BaseElement {
|
||||
value: string = ""
|
||||
default: string = ""
|
||||
placeholder: string = "Placeholder"
|
||||
required: boolean = false
|
||||
name: string = ""
|
||||
@ -17,8 +17,7 @@ export default class InputElement extends BaseElement {
|
||||
super.toJSON(),
|
||||
{
|
||||
'placeHolder': this.placeholder,
|
||||
'xmlType': this.xmlType,
|
||||
'value': this.value,
|
||||
'default': this.default,
|
||||
'name': this.name,
|
||||
'required': this.required
|
||||
})
|
||||
@ -27,9 +26,8 @@ export default class InputElement extends BaseElement {
|
||||
fromJSON(obj) {
|
||||
super.fromJSON(obj)
|
||||
this.name = obj.name
|
||||
this.value = obj.value
|
||||
this.default = obj.default
|
||||
this.required = obj.required
|
||||
this.xmlType = obj.xmlType
|
||||
this.placeHolder = obj.placeHolder
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,76 @@
|
||||
import BaseElement from "./BaseElement";
|
||||
import Column from "./Column.ts"
|
||||
|
||||
export default class Row extends BaseElement {
|
||||
columns: Column[] = []
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
this.type = 7
|
||||
}
|
||||
|
||||
addColumn(column: Column) {
|
||||
this.columns.push(column)
|
||||
}
|
||||
|
||||
public toJSON() {
|
||||
return Object.assign(
|
||||
super.toJSON(),
|
||||
{
|
||||
'columns': this.columns.reduce((result, column) => {
|
||||
result.push(column.toJSON())
|
||||
return result
|
||||
}, [])
|
||||
})
|
||||
}
|
||||
|
||||
cutItem(existingUuid: string) {
|
||||
let item: BaseElement|null = null;
|
||||
this.columns.some((col,indexArray) => {
|
||||
item = col.cutItem(existingUuid)
|
||||
if(item !== null) {
|
||||
return true
|
||||
}
|
||||
});
|
||||
return item
|
||||
}
|
||||
|
||||
getItem(existingUuid: string) {
|
||||
let item: BaseElement|null = null;
|
||||
this.columns.some((col,indexArray) => {
|
||||
item = col.getItem(existingUuid)
|
||||
if(item !== null) {
|
||||
return item;
|
||||
}
|
||||
});
|
||||
return item
|
||||
}
|
||||
|
||||
|
||||
insertItem(item: BaseElement, targetUuid: string): boolean {
|
||||
this.columns.some((col,indexArray) => {
|
||||
item = col.insertItem(item, targetUuid)
|
||||
if(item !== null) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return false
|
||||
}
|
||||
|
||||
insertItemInEmptyColumn(item: BaseElement, targetUuid: string, column: Column) {
|
||||
if(this.uuid == targetUuid) {
|
||||
column.items.push(item)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fromJSON(obj) {
|
||||
super.fromJSON(obj)
|
||||
obj.columns.map((d) => {
|
||||
const column = new Column()
|
||||
column.fromJSON(d)
|
||||
this.columns.push(column)
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
import BaseElement from "./BaseElement";
|
||||
import Option from "./select/Option.ts"
|
||||
|
||||
export default class SelectElement extends BaseElement {
|
||||
default: string = ""
|
||||
name: string = ""
|
||||
xmlType: string = "select"
|
||||
options: Option[] = []
|
||||
mode: string = "normal"
|
||||
container: string = ""
|
||||
constructor() {
|
||||
super()
|
||||
this.type = 3
|
||||
}
|
||||
|
||||
addOption(option: SelectElementOption) {
|
||||
this.options.push(option)
|
||||
}
|
||||
|
||||
public toJSON() {
|
||||
return Object.assign(
|
||||
super.toJSON(),
|
||||
{
|
||||
'default': this.default,
|
||||
'mode': this.mode,
|
||||
'container': this.container,
|
||||
'options': this.options.reduce((result, opt) => {
|
||||
result.push(opt.toJSON())
|
||||
return result
|
||||
}, []),
|
||||
'name': this.name,
|
||||
})
|
||||
}
|
||||
|
||||
fromJSON(obj) {
|
||||
super.fromJSON(obj)
|
||||
this.name = obj.name
|
||||
this.mode = obj.mode
|
||||
this.container = obj.container
|
||||
this.default = obj.default
|
||||
obj.options.map((d) => {
|
||||
const option = new Option()
|
||||
option.fromJSON(d)
|
||||
this.options.push(option)
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
import BaseElement from "./BaseElement";
|
||||
|
||||
export default class TextElement extends BaseElement {
|
||||
default: string = ""
|
||||
name: string = ""
|
||||
xmlType: string = "text"
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.type = 4
|
||||
}
|
||||
|
||||
public toJSON() {
|
||||
return Object.assign(
|
||||
super.toJSON(),
|
||||
{
|
||||
'default': this.default,
|
||||
'name': this.name,
|
||||
})
|
||||
}
|
||||
|
||||
fromJSON(obj) {
|
||||
super.fromJSON(obj)
|
||||
this.name = obj.name
|
||||
this.default = obj.default
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
import BaseElement from "./BaseElement";
|
||||
|
||||
export default class TextareaElement extends BaseElement {
|
||||
default: string = ""
|
||||
name: string = ""
|
||||
xmlType: string = "text"
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.type = 5
|
||||
}
|
||||
|
||||
public toJSON() {
|
||||
return Object.assign(
|
||||
super.toJSON(),
|
||||
{
|
||||
'default': this.default,
|
||||
'name': this.name,
|
||||
})
|
||||
}
|
||||
|
||||
fromJSON(obj) {
|
||||
super.fromJSON(obj)
|
||||
this.name = obj.name
|
||||
this.default = obj.default
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
import {v4 as uuidv4} from 'uuid'
|
||||
import Dependency from '../Dependency.ts'
|
||||
|
||||
export default class Option {
|
||||
uuid: string = "";
|
||||
id: string = ""
|
||||
name: string = ""
|
||||
|
||||
dependencys: Dependency[] = [];
|
||||
|
||||
constructor(id: string) {
|
||||
this.uuid = uuidv4();
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
addDependency(dep: Dependeny)
|
||||
{
|
||||
this.dependencys.push(dep)
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return {
|
||||
'id': this.id,
|
||||
'name': this.name,
|
||||
'dependencys': this.dependencys.reduce((result, dep) => {
|
||||
result.push(dep.toJSON())
|
||||
return result
|
||||
}, [])
|
||||
}
|
||||
}
|
||||
|
||||
fromJSON(obj) {
|
||||
this.name = obj.name
|
||||
this.id = obj.id
|
||||
obj.dependencys.map((d) => {
|
||||
const dep = new Dependency()
|
||||
dep.fromJSON(d)
|
||||
this.dependencys.push(dep)
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -10,15 +10,18 @@ export const useElementStore = defineStore('items', {
|
||||
items: [] as BaseElement[],
|
||||
activeItem: {} as BaseElement | {},
|
||||
showProperties: false,
|
||||
showDependency: false,
|
||||
sourceDragUuid: "",
|
||||
dragMode: "",
|
||||
json: ""
|
||||
json: "",
|
||||
name: uuidv4(),
|
||||
}),
|
||||
getters: {
|
||||
getCount: (state) => state.items.length,
|
||||
getItems: (state) => state.items,
|
||||
getActiveItem: (state) => state.activeItem as BaseElement,
|
||||
isShowPropierties: (state) => state.showProperties,
|
||||
isShowDependency: (state) => state.showDependency,
|
||||
getSourceDragUuid: (state) => state.sourceDragUuid,
|
||||
getDragMode: (state) => state.dragMode,
|
||||
},
|
||||
@ -33,19 +36,23 @@ export const useElementStore = defineStore('items', {
|
||||
}, [])
|
||||
|
||||
|
||||
this.json = JSON.stringify({
|
||||
this.json = JSON.stringify([{
|
||||
uuid: this.uuid,
|
||||
name: this.name,
|
||||
options: options
|
||||
})
|
||||
}])
|
||||
|
||||
},
|
||||
parseJSON() {
|
||||
this.items = []
|
||||
let obj = JSON.parse(this.json)
|
||||
this.name = obj.name
|
||||
obj.options.map((obj) => {
|
||||
const item = Parser.getModelForType(obj.type);
|
||||
item.fromJSON(obj)
|
||||
this.name = obj[0].name
|
||||
if(obj[0].uuid) {
|
||||
this.uuid = obj[0].uuid
|
||||
}
|
||||
obj[0].options.map((ob) => {
|
||||
const item = Parser.getModelForType(ob.type);
|
||||
item.fromJSON(ob)
|
||||
this.addElement(item)
|
||||
})
|
||||
},
|
||||
@ -60,6 +67,9 @@ export const useElementStore = defineStore('items', {
|
||||
})
|
||||
this.showProperties = false
|
||||
},
|
||||
setShowDependency(value: boolean) {
|
||||
this.showDependency = value;
|
||||
},
|
||||
setShowProperties(value: boolean) {
|
||||
this.showProperties = value;
|
||||
},
|
||||
@ -75,29 +85,48 @@ export const useElementStore = defineStore('items', {
|
||||
this.items[i].deleteItem(item)
|
||||
}
|
||||
},
|
||||
moveSortItemToEmptyElement(targetUuid: string, column: Number) {
|
||||
const item = this.cutItem(this.items, this.sourceDragUuid);
|
||||
moveSortItemToEmptyElement(targetUuid: string, column: Column) {
|
||||
const item = this.cutItem(this.sourceDragUuid);
|
||||
this.insertItemInEmptyColumn(this.items, item!, targetUuid, column)
|
||||
|
||||
},
|
||||
moveItemBefore(dragUuid: string, targetUuid: string): boolean {
|
||||
const item = this.cutItem(this.items, dragUuid);
|
||||
return this.insertItem(this.items, item!, targetUuid)
|
||||
const item = this.cutItem(dragUuid);
|
||||
return this.insertItem(this.items, item, targetUuid)
|
||||
},
|
||||
addElementAfter(item: BaseElement, targetUuid: string) {
|
||||
this.insertItem(this.items, item!, targetUuid)
|
||||
this.insertItem(this.items, item, targetUuid)
|
||||
},
|
||||
setSourceDragUuid(uuid: string) {
|
||||
this.sourceDragUuid = uuid
|
||||
},
|
||||
cutItem(items: BaseElement[], existingUuid: string) {
|
||||
cutItem(existingUuid: string) {
|
||||
let item: BaseElement|null = null;
|
||||
items.forEach((element,indexArray) => {
|
||||
this.items.some((element,indexArray) => {
|
||||
if(element.uuid === existingUuid) {
|
||||
item = items.splice(indexArray, 1)[0];
|
||||
item = this.items.splice(indexArray, 1)[0]
|
||||
return true
|
||||
}
|
||||
if(item === null) {
|
||||
item = element.cutItem(existingUuid)
|
||||
if(item !== null) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
});
|
||||
return item;
|
||||
},
|
||||
getItem(existingUuid: string) {
|
||||
let item: BaseElement|null = null;
|
||||
item = this.items.some((element,indexArray) => {
|
||||
if(element.uuid === existingUuid) {
|
||||
return element
|
||||
}
|
||||
if(item === null) {
|
||||
item = element.getItem(existingUuid)
|
||||
if(item !== null) {
|
||||
return item
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
@ -118,7 +147,7 @@ export const useElementStore = defineStore('items', {
|
||||
|
||||
return inserted
|
||||
},
|
||||
insertItemInEmptyColumn(items: BaseElement[], item: BaseElement, targetUuid: string, column: Number): boolean {
|
||||
insertItemInEmptyColumn(items: BaseElement[], item: BaseElement, targetUuid: string, column: Column): boolean {
|
||||
let inserted = false;
|
||||
for (let i = 0; i < items.length; ++i) {
|
||||
inserted = items[i].insertItemInEmptyColumn(item, targetUuid, column)
|
||||
@ -126,6 +155,7 @@ export const useElementStore = defineStore('items', {
|
||||
|
||||
return inserted
|
||||
},
|
||||
|
||||
setDragMode(mode: string) {
|
||||
this.dragMode = mode
|
||||
}
|
||||
|
||||
@ -14,7 +14,6 @@ $this->headScript()->prependFile('/'. $this->designPath . '/js/saxoprint.js');
|
||||
|
||||
</script>
|
||||
|
||||
<button onclick="sendHeight();">iFrame Höhe neu ermitteln</button>
|
||||
<!--
|
||||
<div class="md:flex mt-10 md:w-2/4 md:m-auto gap-10 ml-2 mr-2 md:mt-10">
|
||||
<div class="md:w-1/2">
|
||||
|
||||
@ -37,9 +37,9 @@
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="h-screen text-all font-lenzFont" x-data="{scrolledFromTop: false}" @scroll.window="window.pageYOffset > 60 ? scrolledFromTop = true: scrolledFromTop = false">
|
||||
<body class="text-all font-lenzFont">
|
||||
|
||||
<div class="loading hidden absolute bg-white bg-opacity-60 z-40 h-full w-full flex items-center justify-center">
|
||||
<div class="loading hidden absolute bg-white bg-opacity-60 z-40 w-full flex items-center justify-center">
|
||||
<div class="flex items-center">
|
||||
<span class="text-3xl mr-4">Loading</span>
|
||||
<svg class="animate-spin h-8 w-8 text-gray-800" xmlns="http://www.w3.org/2000/svg" fill="none"
|
||||
@ -79,11 +79,19 @@
|
||||
<script>
|
||||
function sendHeight() {
|
||||
const height = document.body.scrollHeight;
|
||||
parent.postMessage({ height: height }, "https://kalendercreator.de");
|
||||
//alert('Sie sollten doch nicht drücken!');
|
||||
parent.postMessage({ action: 'setHeight', data: {height: height} }, "*");
|
||||
}
|
||||
window.addEventListener("load", sendHeight);
|
||||
window.addEventListener("resize", sendHeight);
|
||||
|
||||
|
||||
|
||||
<?php if($this->user): ?>
|
||||
parent.postMessage({ action: 'setUsername', data: {username: '<?= $this->user->self_email ?>'} }, "*");
|
||||
<?php else: ?>
|
||||
parent.postMessage({ action: 'clearUsername', data: {} }, "*");
|
||||
<?php endif; ?>
|
||||
|
||||
</script>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js" integrity="sha512-v2CJ7UaYy4JwqLDIrZUI/4hqeoQieOmAZNXBeQyjo21dadnwR+8ZaIJVT8EE2iyI61OV8e6M8PP2/4hpQINQ/g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
|
||||
@ -0,0 +1,3 @@
|
||||
<script>
|
||||
parent.postMessage({action: 'redirectLogin'}, '*');
|
||||
</script>
|
||||
@ -0,0 +1,3 @@
|
||||
<script>
|
||||
parent.postMessage({action: 'redirectLogout'}, '*');
|
||||
</script>
|
||||
@ -1,4 +1,4 @@
|
||||
<div class="md:columns-2 md:w-2/4 w-3/4 m-auto mt-5">
|
||||
<div class="md:columns-2 md:w-3/4 w-3/4 m-auto">
|
||||
<div class="break-inside-avoid-column mb-5">
|
||||
<h4 class="text-2xl text-highlight mb-4"><?php if(!$this->shop->private): ?><?php echo $this->translate('Wenn Sie bereits Kunde sind') ?><?php endif; ?></h4>
|
||||
<div class="border border-slate-200 p-5">
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<?= $this->partial ( 'user_tabs.phtml', array ('shop' => $this->shop, 'articlegroup' => $this->articlegroup, 'mode' => $this->mode, 'inworkCount' => $this->inworkCount, 'currency' => $this->currency, 'designPath' => $this->designPath ) );?>
|
||||
|
||||
<div class="w-3/4 md:w-2/4 m-auto">
|
||||
<div class="w-3/4 m-auto">
|
||||
<h2 class="mb-1 text-lg"><?php echo $this->translate('Rechnungsadressen')?></h2>
|
||||
<div class="relative rounded-xl overflow-auto border bg-gray-200 border-gray-300">
|
||||
<div class="shadow-sm overflow-hidden my-4 ">
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<?= $this->partial ( 'user_tabs.phtml', array ('shop' => $this->shop, 'articlegroup' => $this->articlegroup, 'mode' => $this->mode, 'inworkCount' => $this->inworkCount, 'currency' => $this->currency, 'designPath' => $this->designPath ) );?>
|
||||
|
||||
<div class="w-3/4 md:w-2/4 m-auto">
|
||||
<div class="w-3/4 m-auto">
|
||||
<?php if(Zend_Auth::getInstance()->hasIdentity()==true): ?>
|
||||
<?= $this->partial('completeform.phtml', array('buttonName' => 'Speichern', 'buttonClass' => '', 'form' => $this->form)) ?>
|
||||
<?php endif; ?>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<?= $this->partial ( 'user_tabs.phtml', array ('shop' => $this->shop, 'articlegroup' => $this->articlegroup, 'mode' => $this->mode, 'inworkCount' => $this->inworkCount, 'currency' => $this->currency, 'designPath' => $this->designPath ) );?>
|
||||
|
||||
<div class="w-3/4 md:w-2/4 m-auto mt-5">
|
||||
<div class="w-3/4 m-auto mt-5">
|
||||
<?php if(Zend_Auth::getInstance()->hasIdentity()==true): ?>
|
||||
|
||||
<?php echo $this->paginationControl($this->paginator, 'Sliding', 'pagination.phtml'); ?>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<?= $this->partial ( 'user_tabs.phtml', array ('shop' => $this->shop, 'articlegroup' => $this->articlegroup, 'mode' => $this->mode, 'inworkCount' => $this->inworkCount, 'currency' => $this->currency, 'designPath' => $this->designPath ) );?>
|
||||
|
||||
<div class="w-3/4 md:w-2/4 m-auto">
|
||||
<div class="w-3/4 m-auto">
|
||||
<div class="border border-gray-300 bg-gray-200 p-2 flex" style="">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 mr-3">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="m2.25 12 8.954-8.955c.44-.439 1.152-.439 1.591 0L21.75 12M4.5 9.75v10.125c0 .621.504 1.125 1.125 1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75M8.25 21h8.25" />
|
||||
@ -8,7 +8,7 @@
|
||||
<?php echo $this->translate('Hallo')?> <?php echo $this->user->self_firstname ?> <?php echo $this->user->self_lastname ?>, <?php echo $this->translate('verwalten Sie hier Ihr Benutzerkonto')?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-3/4 md:w-2/4 mt-4 md:flex md:space-x-2 m-auto">
|
||||
<div class="w-3/4 mt-4 md:flex md:space-x-2 m-auto">
|
||||
<div class="flex-1 border border-gray-300 bg-gray-200 p-2">
|
||||
<h3 class="text-highlight text-lg"><?php echo $this->translate('Zur Startseite')?></h3>
|
||||
<a class="underline font-bold" href="/"><?php echo $this->translate("Los geht's")?></a>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<?= $this->partial ( 'user_tabs.phtml', array ('shop' => $this->shop, 'articlegroup' => $this->articlegroup, 'mode' => $this->mode, 'inworkCount' => $this->inworkCount, 'currency' => $this->currency, 'designPath' => $this->designPath ) );?>
|
||||
|
||||
<div class="w-3/4 md:w-2/4 m-auto">
|
||||
<div class="w-3/4 m-auto">
|
||||
<div class="border border-gray-300 bg-gray-200 p-2 flex" style="">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 mr-3">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="m2.25 12 8.954-8.955c.44-.439 1.152-.439 1.591 0L21.75 12M4.5 9.75v10.125c0 .621.504 1.125 1.125 1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75M8.25 21h8.25" />
|
||||
@ -9,7 +9,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="w-3/4 md:w-2/4 m-auto">
|
||||
<div class="w-3/4 m-auto">
|
||||
<?php if(Zend_Auth::getInstance()->hasIdentity()==true): ?>
|
||||
<?= $this->partial('completeform.phtml', array('buttonName' => 'Speichern', 'buttonClass' => '', 'form' => $this->form)) ?>
|
||||
<?php endif; ?>
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
<div class="w-3/4 md:w-2/4 m-auto mt-5">
|
||||
<div class="w-3/4 m-auto">
|
||||
<?= $this->partial('completeform.phtml', array('buttonName' => 'Registrieren', 'buttonClass' => '', 'form' => $this->form)) ?>
|
||||
</div>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<div class="md:w-2/4 w-3/4 m-auto mt-5">
|
||||
<div class="md:w-2/4 w-3/4 m-auto">
|
||||
|
||||
<h1 class="text-lg mb-2"><?php echo $this->translate('Passwort vergessen?') ?></h1>
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<div class="border border-gray-300 mt-10 md:w-2/4 mb-4 m-auto">
|
||||
<div class="border border-gray-300 md:w-3/4 mb-4 m-auto">
|
||||
<div class="bg-gray-200 divide-x md:flex w-full text-lg text-center">
|
||||
<div class="flex-auto <?= ($this->mode == 1)? 'text-white border-gray-300 bg-lenzBlue':''; ?>"><a href="/user/myoverview"><?= $this->translate('Übersicht', 'text') ?></a></div>
|
||||
<div class="flex-auto <?= ($this->mode == 2)? 'text-white border-gray-300 bg-lenzBlue':''; ?>"><a href="/user/mysettings"><?= $this->translate('Meine Einstellungen', 'text') ?></a></div>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user