Fixes
Some checks failed
Gitea Actions / Run-Tests-On-Arm64 (push) Failing after 9m30s
Gitea Actions / Run-Tests-On-Amd64 (push) Failing after 11m45s
Gitea Actions / Merge (push) Successful in 3m49s

This commit is contained in:
Thomas Peterson 2025-06-30 20:11:01 +02:00
parent 5ce737a749
commit ab2971e56d
93 changed files with 761 additions and 486 deletions

View File

@ -57,9 +57,7 @@ RUN apt-get update && apt-get install -y \
unzip \ unzip \
libzip-dev \ libzip-dev \
mupdf-tools \ mupdf-tools \
imagemagick \ imagemagick
libmcrypt-dev
# Install fileinfo # Install fileinfo
RUN docker-php-ext-install -j$(nproc) fileinfo RUN docker-php-ext-install -j$(nproc) fileinfo
# Install intl # Install intl
@ -69,9 +67,6 @@ RUN docker-php-ext-install -j$(nproc) intl
# Install mongodb # Install mongodb
RUN pecl install mongodb \ RUN pecl install mongodb \
&& docker-php-ext-enable mongodb && docker-php-ext-enable mongodb
# Install mcrypt
RUN pecl install mcrypt \
&& docker-php-ext-enable mcrypt
# Install curl # Install curl
RUN docker-php-ext-install -j$(nproc) curl RUN docker-php-ext-install -j$(nproc) curl
# Install Zip # Install Zip
@ -97,8 +92,10 @@ RUN apt-get update && apt-get install -y \
# Install ldap # Install ldap
RUN docker-php-ext-install -j$(nproc) ldap RUN docker-php-ext-install -j$(nproc) ldap
RUN docker-php-ext-configure imap --with-kerberos --with-imap-ssl && \ #RUN docker-php-ext-configure imap --with-kerberos --with-imap-ssl && \
docker-php-ext-install -j$(nproc) imap # docker-php-ext-install -j$(nproc) imap
RUN pecl install imap
# COPY ./.docker/images/php/base/pdf/php_pdflib.so /pdflib.so # COPY ./.docker/images/php/base/pdf/php_pdflib.so /pdflib.so

View File

@ -0,0 +1,20 @@
<?php
namespace Plugin\Custom\PSC\FormBuilder\Controller\Backend;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
use Symfony\Component\Routing\Annotation\Route;
#[Route('/index')]
class IndexController extends AbstractController
{
#[Template]
#[Security("is_granted('ROLE_USER')")]
#[Route(path: '/create', name: 'psc_backend_invoice_index_create')]
public function indexAction(JWTTokenManagerInterface $jwtManager)
{
return array('jwt' => $jwtManager->create($this->getUser()));
}
}

View File

@ -1,64 +0,0 @@
import {v4 as uuidv4} from 'uuid'
import Dependency from './Dependency.ts'
export default class Border {
uuid: string = "";
formula: string = "";
calcValue: string = "";
calcValue1: string = "";
calcValue2: string = "";
calcValue3: string = "";
calcValue4: string = "";
calcValue5: string = "";
calcValue6: string = "";
calcValue7: string = "";
calcValue8: string = "";
calcValue9: string = "";
calcValue10: string = "";
flatRate: string = "";
value: string = "";
dependencys: Dependency[] = [];
constructor() {
this.uuid = uuidv4();
}
addDependency(dep: Dependeny)
{
this.dependencys.push(dep)
}
toJSON() {
return {
'formula': this.formula,
'calcValue': this.calcValue,
'calcValue1': this.calcValue1,
'calcValue2': this.calcValue2,
'calcValue3': this.calcValue3,
'calcValue4': this.calcValue4,
'calcValue5': this.calcValue5,
'calcValue6': this.calcValue6,
'calcValue7': this.calcValue7,
'calcValue8': this.calcValue8,
'calcValue9': this.calcValue9,
'calcValue10': this.calcValue10,
'flatRate': this.flatRate,
'value': this.value,
'dependencys': this.dependencys.reduce((result, dep) => {
result.push(dep.toJSON())
return result
}, [])
}
}
fromJSON(obj) {
this.formula = obj.formula
this.value = obj.value
this.flatRate = obj.flatRate
this.calcValue = obj.calcValue
obj.dependencys.map((d) => {
const dep = new Dependency()
dep.fromJSON(d)
this.dependencys.push(dep)
})
}
}

View File

@ -8,6 +8,7 @@
"@vueuse/core": "^13.4.0", "@vueuse/core": "^13.4.0",
"class-variance-authority": "^0.7.1", "class-variance-authority": "^0.7.1",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"ky": "^1.8.1",
"lucide-vue-next": "^0.514.0", "lucide-vue-next": "^0.514.0",
"pinia": "^3.0.3", "pinia": "^3.0.3",
"reka-ui": "^2.3.1", "reka-ui": "^2.3.1",
@ -420,6 +421,8 @@
"kolorist": ["kolorist@1.8.0", "", {}, "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ=="], "kolorist": ["kolorist@1.8.0", "", {}, "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ=="],
"ky": ["ky@1.8.1", "", {}, "sha512-7Bp3TpsE+L+TARSnnDpk3xg8Idi8RwSLdj6CMbNWoOARIrGrbuLGusV0dYwbZOm4bB3jHNxSw8Wk/ByDqJEnDw=="],
"lightningcss": ["lightningcss@1.30.1", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-darwin-arm64": "1.30.1", "lightningcss-darwin-x64": "1.30.1", "lightningcss-freebsd-x64": "1.30.1", "lightningcss-linux-arm-gnueabihf": "1.30.1", "lightningcss-linux-arm64-gnu": "1.30.1", "lightningcss-linux-arm64-musl": "1.30.1", "lightningcss-linux-x64-gnu": "1.30.1", "lightningcss-linux-x64-musl": "1.30.1", "lightningcss-win32-arm64-msvc": "1.30.1", "lightningcss-win32-x64-msvc": "1.30.1" } }, "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg=="], "lightningcss": ["lightningcss@1.30.1", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-darwin-arm64": "1.30.1", "lightningcss-darwin-x64": "1.30.1", "lightningcss-freebsd-x64": "1.30.1", "lightningcss-linux-arm-gnueabihf": "1.30.1", "lightningcss-linux-arm64-gnu": "1.30.1", "lightningcss-linux-arm64-musl": "1.30.1", "lightningcss-linux-x64-gnu": "1.30.1", "lightningcss-linux-x64-musl": "1.30.1", "lightningcss-win32-arm64-msvc": "1.30.1", "lightningcss-win32-x64-msvc": "1.30.1" } }, "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg=="],
"lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.30.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ=="], "lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.30.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ=="],

View File

@ -5,6 +5,7 @@
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"check": "vue-tsc -b",
"build": "vue-tsc -b && vite build", "build": "vue-tsc -b && vite build",
"preview": "vite preview" "preview": "vite preview"
}, },
@ -13,6 +14,7 @@
"@vueuse/core": "^13.4.0", "@vueuse/core": "^13.4.0",
"class-variance-authority": "^0.7.1", "class-variance-authority": "^0.7.1",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"ky": "^1.8.1",
"lucide-vue-next": "^0.514.0", "lucide-vue-next": "^0.514.0",
"pinia": "^3.0.3", "pinia": "^3.0.3",
"reka-ui": "^2.3.1", "reka-ui": "^2.3.1",

View File

@ -3,13 +3,13 @@ import {
ResizableHandle, ResizableHandle,
ResizablePanel, ResizablePanel,
ResizablePanelGroup, ResizablePanelGroup,
} from '@/components/ui/resizable' } from '../components/ui/resizable'
import { Library } from '@/components/app/library' import { Library } from '../components/app/library'
import { Debug } from '@/components/app/debug' import { Debug } from '../components/app/debug'
import { ElementProperties } from '@/components/app/elementproperties' import { ElementProperties } from '../components/app/elementproperties'
import { ElementDependency } from '@/components/app/elementdependency' import { ElementDependency } from '../components/app/elementdependency'
import { Main } from '@/components/app/main' import { Main } from '../components/app/main'
</script> </script>
<template> <template>

View File

@ -1,8 +1,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { useElementStore } from '@/stores/Items'; import { useElementStore } from '../../../stores/Items';
import { Textarea } from '@/components/ui/textarea' import { Textarea } from '../../../components/ui/textarea'
import { Button } from '@/components/ui/button' import { Button } from '../../../components/ui/button'
import { ref } from 'vue'
const store = useElementStore() const store = useElementStore()
function loadJson() { function loadJson() {

View File

@ -1,23 +1,19 @@
<script lang="ts" setup> <script lang="ts" setup>
import { useElementStore } from '@/stores/Items' import { Input } from '../../../components/ui/input'
import { Input } from '@/components/ui/input' import { Button } from '../../../components/ui/button'
import { Button } from '@/components/ui/button'
import { Select,SelectContent,SelectItem,SelectTrigger,SelectValue } from '@/components/ui/select'
import Border from '../../../model/Border.ts' import Border from '../../../model/Border.ts'
import { default as DepModel } from '../../../model/Dependency.ts' import { default as DepModel } from '../../../model/Dependency.ts'
import { Dependency } from '../elementdependency' import { Dependency } from '../elementdependency'
const props = defineProps({ defineProps<{
borders: Array as PropType<Border[]> borders: Border[]
}) }>()
function addDependency(border) { function addDependency(border: Border) {
border.addDependency(new DepModel()); border.addDependency(new DepModel());
} }
const store = useElementStore()
</script> </script>
<template> <template>

View File

@ -1,23 +1,10 @@
<script lang="ts" setup> <script lang="ts" setup>
import { useElementStore } from '@/stores/Items'
import { Input } from '@/components/ui/input'
import { Button } from '@/components/ui/button'
import { Dependency } from '.'
import { Border } from '.' import { Border } from '.'
import { default as DepModel } from '../../../model/Dependency.ts' import Dependency from '../../../model/Dependency.ts'
import { default as BorderModel } from '../../../model/Border.ts'
import type { PropType } from 'vue'
const props = defineProps({
dependency: Object as PropType<DepModel>
})
const store = useElementStore()
function addBorder(dep) {
dep.addBorder(new BorderModel());
}
defineProps<{
dependency: Dependency
}>()
</script> </script>

View File

@ -1,20 +1,20 @@
<script lang="ts" setup> <script lang="ts" setup>
import { useElementStore } from '@/stores/Items' import { useElementStore } from '../../../stores/Items'
import { Input } from '@/components/ui/input' import { Input } from '../../../components/ui/input'
import { Button } from '@/components/ui/button' import { Button } from '../../../components/ui/button'
import { Label } from '@/components/ui/label' import { Label } from '../../../components/ui/label'
import { Select,SelectContent,SelectItem,SelectTrigger,SelectValue } from '@/components/ui/select' import { Select,SelectContent,SelectItem,SelectTrigger,SelectValue } from '../../../components/ui/select'
import Deptendency from '../../../model/Dependency.ts' import Dependency from '../../../model/Dependency.ts'
import { ElementBorder } from '../elementborder' import { ElementBorder } from '../elementborder'
import Border from '../../../model/Border.ts' import Border from '../../../model/Border.ts'
const props = defineProps({ defineProps<{
dependencys: Array as PropType<Dependency[]> dependencys: Dependency[]
}) }>()
const store = useElementStore() const store = useElementStore()
function addBorder(dep) { function addBorder(dep: Dependency) {
dep.addBorder(new Border()) dep.addBorder(new Border())
} }

View File

@ -1,8 +1,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { ref, watch } from 'vue' import { ref, watch } from 'vue'
import { useElementStore } from '@/stores/Items' import { useElementStore } from '../../../stores/Items'
import { Input } from '@/components/ui/input' import { Button } from '../../../components/ui/button'
import { Button } from '@/components/ui/button'
import { Dependency } from '.' import { Dependency } from '.'
import { default as DepModel } from '../../../model/Dependency.ts' import { default as DepModel } from '../../../model/Dependency.ts'
import { import {
@ -12,13 +11,13 @@ import {
DialogFooter, DialogFooter,
DialogHeader, DialogHeader,
DialogTitle, DialogTitle,
DialogTrigger, } from '../../../components/ui/dialog'
} from '@/components/ui/dialog'
const store = useElementStore() const store = useElementStore()
let openModal = ref(false) let openModal = ref(false)
function addDependency(event) { function addDependency() {
store.getActiveItem.addDependency(new DepModel()); store.getActiveItem.addDependency(new DepModel());
} }
@ -44,7 +43,7 @@ watch(openModal, (newOpenModal) => {
</DialogDescription> </DialogDescription>
</DialogHeader> </DialogHeader>
<div class="overflow-auto h-full w-full"> <div class="overflow-auto h-full w-full">
<Button v-on:click="addDependency($event)">Add Dependency</Button> <Button v-on:click="addDependency()">Add Dependency</Button>
<Dependency :dependencys="store.getActiveItem.dependencys" /> <Dependency :dependencys="store.getActiveItem.dependencys" />
</div> </div>

View File

@ -1,14 +1,16 @@
<script lang="ts" setup> <script lang="ts" setup>
import { useElementStore } from '@/stores/Items' import { useElementStore } from '../../../stores/Items'
import InputElement from '@/model/InputElement' import InputElement from '../../../model/InputElement'
import SelectElement from '@/model/SelectElement' import SelectElement from '../../../model/SelectElement'
import HiddenElement from '@/model/HiddenElement' import MediaElement from '../../../model/MediaElement'
import TextElement from '@/model/TextElement' import HiddenElement from '../../../model/HiddenElement'
import Row from '@/model/Row' import TextElement from '../../../model/TextElement'
import TextareaElement from '@/model/TextareaElement' import Row from '../../../model/Row'
import HeadlineElement from '@/model/HeadlineElement' import TextareaElement from '../../../model/TextareaElement'
import HeadlineElement from '../../../model/HeadlineElement'
import InputElementProperties from '../properties/InputElement.vue' import InputElementProperties from '../properties/InputElement.vue'
import SelectElementProperties from '../properties/SelectElement.vue' import SelectElementProperties from '../properties/SelectElement.vue'
import MediaElementProperties from '../properties/MediaElement.vue'
import HiddenElementProperties from '../properties/HiddenElement.vue' import HiddenElementProperties from '../properties/HiddenElement.vue'
import TextElementProperties from '../properties/TextElement.vue' import TextElementProperties from '../properties/TextElement.vue'
import TextareaElementProperties from '../properties/TextareaElement.vue' import TextareaElementProperties from '../properties/TextareaElement.vue'
@ -17,14 +19,11 @@ import RowProperties from '../properties/RowElement.vue'
import { ref, watch } from 'vue' import { ref, watch } from 'vue'
import { import {
Sheet, Sheet,
SheetClose,
SheetContent, SheetContent,
SheetDescription, SheetDescription,
SheetFooter,
SheetHeader, SheetHeader,
SheetTitle, SheetTitle,
SheetTrigger, } from '../../../components/ui/sheet'
} from '@/components/ui/sheet'
let openModal = ref(false) let openModal = ref(false)
@ -58,6 +57,12 @@ watch(openModal, (newOpenModal) => {
> >
</HeadlineElementProperties> </HeadlineElementProperties>
<MediaElementProperties
v-if="store.getActiveItem.type === 9"
v-model="store.getActiveItem as MediaElement"
>
</MediaElementProperties>
<RowProperties <RowProperties
v-if="store.getActiveItem.type === 7" v-if="store.getActiveItem.type === 7"
v-model="store.getActiveItem as Row" v-model="store.getActiveItem as Row"

View File

@ -1,15 +1,14 @@
<script lang="ts" setup> <script lang="ts" setup>
import HeadlineElement from '@/model/HeadlineElement'; import HeadlineElement from '../../../model/HeadlineElement';
import { computed } from 'vue'; import { computed } from 'vue';
import { Input } from '@/components/ui/input'
const props = defineProps({ const props = defineProps<{
modelValue: HeadlineElement modelValue: HeadlineElement
}) }>()
let emit = defineEmits(['update:modelValue']); let emit = defineEmits(['update:modelValue']);
const theModel = computed({ const theModel = computed<HeadlineElement>({
get: () => props.modelValue, get: () => props.modelValue,
set: (value) => emit('update:modelValue', value), set: (value) => emit('update:modelValue', value),
}); });
@ -18,12 +17,12 @@ const theModel = computed({
</script> </script>
<template> <template>
<div class="flex gap-2 flex-row items-center content-center"> <div class="flex gap-2 flex-row items-center content-center">
<h1 v-if="theModel.variant == 1" class="text-4xl">{{theModel.default}}</h1> <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> <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> <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> <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> <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> <h2 v-else-if="theModel?.variant == '2'" class="text-3xl">{{theModel?.default}}</h2>
<h1 v-else class="text-4xl">{{theModel.default}}</h1> <h1 v-else class="text-4xl">{{theModel?.default}}</h1>
</div> </div>
</template> </template>

View File

@ -1,12 +1,11 @@
<script lang="ts" setup> <script lang="ts" setup>
import HiddenElement from '@/model/HiddenElement'; import HiddenElement from '../../../model/HiddenElement';
import { computed } from 'vue'; import { computed } from 'vue';
import { Input } from '@/components/ui/input'
import { SquareDashed } from 'lucide-vue-next';
const props = defineProps({ interface Props {
modelValue: HiddenElement modelValue: HiddenElement
}) }
const props = defineProps<Props>()
let emit = defineEmits(['update:modelValue']); let emit = defineEmits(['update:modelValue']);

View File

@ -1,16 +1,15 @@
<script lang="ts" setup> <script lang="ts" setup>
import InputElement from '@/model/InputElement'; import InputElement from '../../../model/InputElement';
import { computed } from 'vue'; import { computed } from 'vue';
import { Input } from '@/components/ui/input' import { Input } from '../../../components/ui/input'
import { SquarePen } from 'lucide-vue-next';
const props = defineProps({ const props = defineProps<{
modelValue: InputElement modelValue: InputElement
}) }>()
let emit = defineEmits(['update:modelValue']); let emit = defineEmits(['update:modelValue']);
const theModel = computed({ const theModel = computed<InputElement>({
get: () => props.modelValue, get: () => props.modelValue,
set: (value) => emit('update:modelValue', value), set: (value) => emit('update:modelValue', value),
}); });
@ -21,6 +20,6 @@ const theModel = computed({
<template> <template>
<div class="flex gap-2 flex-row items-center"> <div class="flex gap-2 flex-row items-center">
<label class="w-60 flex-inital">{{theModel.name}} {{theModel.default}}</label> <label class="w-60 flex-inital">{{theModel.name}} {{theModel.default}}</label>
<Input v-model:placeholder="theModel.placeholder" :modelValue="theModel.default" v-model:name="theModel.name" v-model:id="theModel.id" v-model:required="theModel.required"/> <Input v-model:placeholder="theModel.placeHolder" :modelValue="theModel.default" v-model:name="theModel.name" v-model:id="theModel.id" v-model:required="theModel.required"/>
</div> </div>
</template> </template>

View File

@ -0,0 +1,24 @@
<script lang="ts" setup>
import MediaElement from '../../../model/MediaElement';
import { computed } from 'vue';
interface Props {
modelValue: MediaElement
}
const props = defineProps<Props>()
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">
<label class="w-60 flex-inital">{{theModel.name}}</label>
</div>
</template>

View File

@ -1,19 +1,19 @@
<script lang="ts" setup> <script lang="ts" setup>
import Row from '@/model/Row'; import Row from '../../../model/Row';
import Column from '@/model/Column'; import Column from '../../../model/Column';
import BaseElement from '../../../model/BaseElement';
import { ref, computed } from 'vue'; 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 EmptyElementForm from './EmptyElementForm.vue'
import { RenderElements } from './../renderelements' import { RenderElements } from './../renderelements'
import { useElementStore } from '@/stores/Items' import { useElementStore } from '../../../stores/Items'
import Parser from '@/lib/parser' import Parser from '../../../lib/parser'
import { CirclePlus } from 'lucide-vue-next'; import { CirclePlus } from 'lucide-vue-next';
const props = defineProps({ interface Props {
modelValue: Row modelValue: Row
}) }
const props = defineProps<Props>()
let emit = defineEmits(['update:modelValue']); let emit = defineEmits(['update:modelValue']);
const dragUuid = ref(""); const dragUuid = ref("");
@ -29,8 +29,10 @@ const theModel = computed({
const onDrop = (event: DragEvent, targetUuid: string, column: Column) => { const onDrop = (event: DragEvent, targetUuid: string, column: Column) => {
dragUuid.value = "" dragUuid.value = ""
if(event.dataTransfer?.getData('mode') == "sort") { if(event.dataTransfer?.getData('mode') == "sort") {
let item = store.cutItem(store.getSourceDragUuid) let item: BaseElement|null = store.cutItem(store.getSourceDragUuid)
column.items.push(item) if(item !== null) {
column.items.push(item)
}
store.setDragMode("") store.setDragMode("")
event.stopImmediatePropagation() event.stopImmediatePropagation()
} }
@ -44,14 +46,6 @@ const onDrop = (event: DragEvent, targetUuid: string, column: Column) => {
} }
} }
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) => { const dragLeaveEmpty = (event: DragEvent, uuid: string) => {
dragUuid.value = "" dragUuid.value = ""
event.stopImmediatePropagation() event.stopImmediatePropagation()

View File

@ -1,16 +1,14 @@
<script lang="ts" setup> <script lang="ts" setup>
import SelectElement from '@/model/SelectElement' import SelectElement from '../../../model/SelectElement'
import { computed } from 'vue' import { computed } from 'vue'
import { import {
Select, Select,
SelectContent, SelectContent,
SelectGroup, SelectGroup,
SelectItem, SelectItem,
SelectLabel,
SelectTrigger, SelectTrigger,
SelectValue, SelectValue,
} from '@/components/ui/select' } from '../../../components/ui/select'
import { SquareParking, SquareChevronDown, SquareDashed } from 'lucide-vue-next';
const props = defineProps({ const props = defineProps({
modelValue: SelectElement modelValue: SelectElement

View File

@ -1,16 +1,14 @@
<script lang="ts" setup> <script lang="ts" setup>
import TextElement from '@/model/TextElement'; import TextElement from '../../../model/TextElement';
import { computed } from 'vue'; import { computed } from 'vue';
import { Input } from '@/components/ui/input'
import { SquareParking } from 'lucide-vue-next';
const props = defineProps({ const props = defineProps<{
modelValue: TextElement modelValue: TextElement
}) }>()
let emit = defineEmits(['update:modelValue']); let emit = defineEmits(['update:modelValue']);
const theModel = computed({ const theModel = computed<TextElement>({
get: () => props.modelValue, get: () => props.modelValue,
set: (value) => emit('update:modelValue', value), set: (value) => emit('update:modelValue', value),
}); });

View File

@ -1,16 +1,15 @@
<script lang="ts" setup> <script lang="ts" setup>
import TextareaElement from '@/model/TextareaElement'; import TextareaElement from '../../../model/TextareaElement';
import { computed } from 'vue'; import { computed } from 'vue';
import { Textarea } from '@/components/ui/textarea' import { Textarea } from '../../../components/ui/textarea'
import { SquareMenu } from 'lucide-vue-next';
const props = defineProps({ const props = defineProps<{
modelValue: TextareaElement modelValue: TextareaElement
}) }>()
let emit = defineEmits(['update:modelValue']); let emit = defineEmits(['update:modelValue']);
const theModel = computed({ const theModel = computed<TextareaElement>({
get: () => props.modelValue, get: () => props.modelValue,
set: (value) => emit('update:modelValue', value), set: (value) => emit('update:modelValue', value),
}); });

View File

@ -1,8 +1,8 @@
<script setup lang="ts"> <script setup lang="ts">
import { useElementStore } from '@/stores/Items' import { useElementStore } from '../../../stores/Items'
import { SquareParking, SquareDot, SquareMenu, SquarePen, SquareChevronDown, SquareDashed } from 'lucide-vue-next'; import { Image, SquareParking, SquareDot, SquareMenu, SquarePen, SquareChevronDown, SquareDashed } from 'lucide-vue-next';
import { Switch } from '@/components/ui/switch' import { Switch } from '../../../components/ui/switch'
import { Label } from '@/components/ui/label' import { Label } from '../../../components/ui/label'
import { ref, watch } from 'vue' import { ref, watch } from 'vue'
const store = useElementStore() const store = useElementStore()
@ -10,9 +10,11 @@ const store = useElementStore()
let previewMode = ref(false) let previewMode = ref(false)
function startDrag(event: DragEvent, item: string) { function startDrag(event: DragEvent, item: string) {
event.dataTransfer.dropEffect = 'move'; if(event.dataTransfer) {
event.dataTransfer.effectAllowed = 'move'; event.dataTransfer.dropEffect = 'move'
event.dataTransfer.setData('itemId', item); event.dataTransfer.effectAllowed = 'move'
event.dataTransfer.setData('itemId', item)
}
store.setDragMode("insert") store.setDragMode("insert")
} }
@ -40,6 +42,10 @@ watch(previewMode, (newPreviewMode) => {
<SquareParking /> <SquareParking />
<span>Text</span> <span>Text</span>
</div> </div>
<div id="media" class="border-1 p-2 w-full flex flex-row gap-2" draggable="true" @dragstart="startDrag($event, '9')" @dragenter.prevent @dragover.prevent>
<Image />
<span>Media</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> <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 /> <SquareMenu />
<span>Textarea</span> <span>Textarea</span>

View File

@ -1,10 +1,10 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue' import { RenderElements } from '../../../components/app/renderelements'
import { RenderElements } from '@/components/app/renderelements' import { useElementStore } from '../../../stores/Items'
import { useElementStore } from '@/stores/Items' import Parser from '../../../lib/parser'
import Parser from '@/lib/parser'
const store = useElementStore() const store = useElementStore()
function onDrop(event: DragEvent) { function onDrop(event: DragEvent) {
if(store.dragMode == "insert") { if(store.dragMode == "insert") {
const itemType = Number(event.dataTransfer?.getData('itemId')); const itemType = Number(event.dataTransfer?.getData('itemId'));

View File

@ -1,8 +1,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import HeadlineElement from '@/model/HeadlineElement'; import HeadlineElement from '../../../model/HeadlineElement';
import { computed } from 'vue'; import { computed } from 'vue';
import { Input } from '@/components/ui/input' import { Input } from '../../../components/ui/input'
import { Checkbox } from '@/components/ui/checkbox'
import { import {
Select, Select,
SelectContent, SelectContent,
@ -10,7 +9,7 @@ import {
SelectItem, SelectItem,
SelectTrigger, SelectTrigger,
SelectValue, SelectValue,
} from '@/components/ui/select' } from '../../../components/ui/select'
const props = defineProps({ const props = defineProps({
modelValue: HeadlineElement modelValue: HeadlineElement

View File

@ -1,8 +1,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import HiddenElement from '@/model/HiddenElement'; import HiddenElement from '../../../model/HiddenElement';
import { computed } from 'vue'; import { computed } from 'vue';
import { Input } from '@/components/ui/input' import { Input } from '../../../components/ui/input'
import { Checkbox } from '@/components/ui/checkbox'
const props = defineProps({ const props = defineProps({
modelValue: HiddenElement modelValue: HiddenElement

View File

@ -1,19 +1,19 @@
<script lang="ts" setup> <script lang="ts" setup>
import InputElement from '@/model/InputElement'; import InputElement from '../../../model/InputElement'
import { computed } from 'vue'; import { computed } from 'vue'
import { Input } from '@/components/ui/input' import { Input } from '../../../components/ui/input'
import { Checkbox } from '@/components/ui/checkbox' import { Checkbox } from '../../../components/ui/checkbox'
const props = defineProps({ const props = defineProps<{
modelValue: InputElement modelValue: InputElement
}) }>()
let emit = defineEmits(['update:modelValue']); let emit = defineEmits(['update:modelValue']);
const theModel = computed({ const theModel = computed<InputElement>({
get: () => props.modelValue, get: () => props.modelValue,
set: (value) => emit('update:modelValue', value), set: (value) => emit('update:modelValue', value),
}); })
</script> </script>
@ -21,7 +21,7 @@ const theModel = computed({
<label>ID</label> <label>ID</label>
<Input v-model="theModel!.id" /> <Input v-model="theModel!.id" />
<label>Placeholder</label> <label>Placeholder</label>
<Input v-model="theModel!.placeholder"/> <Input v-model="theModel!.placeHolder"/>
<label>Default</label> <label>Default</label>
<Input v-model="theModel!.default"/> <Input v-model="theModel!.default"/>
<label>Name</label> <label>Name</label>

View File

@ -0,0 +1,29 @@
<script lang="ts" setup>
import MediaElement from '../../../model/MediaElement';
import { computed } from 'vue';
import { Input } from '../../../components/ui/input'
import { useMedia } from '../../../composables/useMedia'
const props = defineProps({
modelValue: MediaElement
})
let emit = defineEmits(['update:modelValue']);
const theModel = computed({
get: () => props.modelValue,
set: (value) => emit('update:modelValue', value),
});
const { media, loading, error } = useMedia()
</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>

View File

@ -1,29 +1,36 @@
<script lang="ts" setup> <script lang="ts" setup>
import Option from '@/model/select/Option'; import Option from '../../../model/select/Option';
import { computed } from 'vue'; import { computed } from 'vue';
import { Input } from '@/components/ui/input' import { Input } from '../../../components/ui/input'
import { Button } from '@/components/ui/button' import { Button } from '../../../components/ui/button'
import { Dependency } from '../elementdependency' import { Dependency } from '../elementdependency'
import { default as DepModel } from '../../../model/Dependency.ts' import { default as DepModel } from '../../../model/Dependency.ts'
const props = defineProps({ const props = defineProps<{
option: Option, option: Option,
}) }>()
function addDependency(option) { function addDependency(option: Option) {
option.addDependency(new DepModel()); option.addDependency(new DepModel());
} }
let emit = defineEmits(['update:option'])
const theModel = computed<Option>({
get: () => props.option,
set: (value) => emit('update:option', value),
})
</script> </script>
<template> <template>
<div class="flex flex-row gap-1"> <div class="flex flex-row gap-1">
<label>ID</label> <label>ID</label>
<Input v-model="option.id" /> <Input v-model="theModel.id" />
<label>Name</label> <label>Name</label>
<Input v-model="option.name"/> <Input v-model="theModel.name"/>
<Button v-on:click="addDependency(option)">Add Dependency</Button> <Button v-on:click="addDependency(theModel)">Add Dependency</Button>
</div> </div>
<Dependency :dependencys="option.dependencys" /> <Dependency :dependencys="theModel.dependencys" />
</template> </template>

View File

@ -1,9 +1,8 @@
<script lang="ts" setup> <script lang="ts" setup>
import Row from '@/model/Row' import Row from '../../../model/Row'
import Column from '@/model/Column' import Column from '../../../model/Column'
import { computed } from 'vue' import { computed } from 'vue'
import { Input } from '@/components/ui/input' import { Button } from '../../../components/ui/button'
import { Button } from '@/components/ui/button'
const props = defineProps({ const props = defineProps({
modelValue: Row modelValue: Row
@ -12,16 +11,18 @@ const props = defineProps({
let emit = defineEmits(['update:modelValue']) let emit = defineEmits(['update:modelValue'])
const theModel = computed({ const theModel = computed({
get: () => props.modelValue, get: () => props.modelValue,
set: (value) => emit('update:modelValue', value), set: (value) => emit('update:modelValue', value),
}) })
function addColumn(row: Row) { function addColumn(row: Row) {
row.addColumn(new Column()) if(row !== null) {
row.addColumn(new Column())
}
} }
</script> </script>
<template> <template>
<Button v-on:click="addColumn(theModel)">add Column</Button> <Button v-on:click="addColumn(theModel!)">add Column</Button>
</template> </template>

View File

@ -1,10 +1,9 @@
<script lang="ts" setup> <script lang="ts" setup>
import SelectElement from '@/model/SelectElement'; import SelectElement from '../../../model/SelectElement';
import Option from '@/model/select/Option'; import Option from '../../../model/select/Option';
import { computed } from 'vue'; import { computed } from 'vue';
import { Input } from '@/components/ui/input' import { Input } from '../../../components/ui/input'
import { Button } from '@/components/ui/button' import { Button } from '../../../components/ui/button'
import { Checkbox } from '@/components/ui/checkbox'
import { import {
Select, Select,
SelectContent, SelectContent,
@ -12,7 +11,7 @@ import {
SelectItem, SelectItem,
SelectTrigger, SelectTrigger,
SelectValue, SelectValue,
} from '@/components/ui/select' } from '../../../components/ui/select'
import OptionElement from './OptionElement.vue' import OptionElement from './OptionElement.vue'
import { import {
Dialog, Dialog,
@ -23,20 +22,20 @@ import {
DialogHeader, DialogHeader,
DialogTitle, DialogTitle,
DialogTrigger, DialogTrigger,
} from '@/components/ui/dialog' } from '../../../components/ui/dialog'
const props = defineProps({ const props = defineProps<{
modelValue: SelectElement modelValue: SelectElement
}) }>()
let emit = defineEmits(['update:modelValue']); let emit = defineEmits(['update:modelValue']);
const theModel = computed({ const theModel = computed<SelectElement>({
get: () => props.modelValue, get: () => props.modelValue,
set: (value) => emit('update:modelValue', value), set: (value) => emit('update:modelValue', value),
}); });
function addOption(obj) { function addOption(obj: SelectElement) {
obj.addOption(new Option(String(obj.options.length + 1))); obj.addOption(new Option(String(obj.options.length + 1)));
} }
</script> </script>

View File

@ -1,20 +1,19 @@
<script lang="ts" setup> <script lang="ts" setup>
import TextElement from '@/model/TextElement'; import TextElement from '../../../model/TextElement';
import { computed } from 'vue'; import { computed } from 'vue';
import { Input } from '@/components/ui/input' import { Input } from '../../../components/ui/input'
import { Textarea } from '@/components/ui/textarea' import { Textarea } from '../../../components/ui/textarea'
import { Checkbox } from '@/components/ui/checkbox'
const props = defineProps({ const props = defineProps<{
modelValue: TextElement modelValue: TextElement
}) }>()
let emit = defineEmits(['update:modelValue']); let emit = defineEmits(['update:modelValue'])
const theModel = computed({ const theModel = computed<TextElement>({
get: () => props.modelValue, get: () => props.modelValue,
set: (value) => emit('update:modelValue', value), set: (value) => emit('update:modelValue', value),
}); })
</script> </script>

View File

@ -1,28 +1,28 @@
<script lang="ts" setup> <script lang="ts" setup>
import TextareaElement from '@/model/TextareaElement'; import TextareaElement from '../../../model/TextareaElement';
import { computed } from 'vue'; import { computed } from 'vue';
import { Input } from '@/components/ui/input' import { Input } from '../../../components/ui/input'
import { Textarea } from '@/components/ui/textarea' import { Textarea } from '../../../components/ui/textarea'
import { Checkbox } from '@/components/ui/checkbox'
const props = defineProps({ const props = defineProps<{
modelValue: TextareaElement modelValue: TextareaElement
}) }>()
let emit = defineEmits(['update:modelValue']); let emit = defineEmits(['update:modelValue']);
const theModel = computed({ const theModel = computed<TextareaElement>({
get: () => props.modelValue, get: () => props.modelValue,
set: (value) => emit('update:modelValue', value), set: (value) => emit('update:modelValue', value),
}); });
</script> </script>
<template> <template>
<label>ID</label> <label>ID</label>
<Input v-model="theModel!.id" /> <Input v-model="theModel.id" />
<label>Name</label> <label>Name</label>
<Input v-model="theModel!.name"/> <Input v-model="theModel.name"/>
<label>Default</label> <label>Default</label>
<Textarea v-model="theModel!.default"/> <Textarea v-model="theModel.default"/>
</template> </template>

View File

@ -1,28 +1,31 @@
<script lang="ts" setup> <script lang="ts" setup>
import BaseElement from '@/model/BaseElement'; import BaseElement from '../../../model/BaseElement';
import InputElementForm from '../elements/InputElementForm.vue' import InputElementForm from '../elements/InputElementForm.vue'
import HiddenElementForm from '../elements/HiddenElementForm.vue' import HiddenElementForm from '../elements/HiddenElementForm.vue'
import HeadlineElementForm from '../elements/HeadlineElementForm.vue' import HeadlineElementForm from '../elements/HeadlineElementForm.vue'
import TextElementForm from '../elements/TextElementForm.vue' import TextElementForm from '../elements/TextElementForm.vue'
import MediaElementForm from '../elements/MediaElementForm.vue'
import TextareaElementForm from '../elements/TextareaElementForm.vue' import TextareaElementForm from '../elements/TextareaElementForm.vue'
import SelectElementForm from '../elements/SelectElementForm.vue' import SelectElementForm from '../elements/SelectElementForm.vue'
import RowElementForm from '../elements/RowElementForm.vue' import RowElementForm from '../elements/RowElementForm.vue'
import InputElement from '@/model/InputElement' import InputElement from '../../../model/InputElement'
import HiddenElement from '@/model/HiddenElement' import HiddenElement from '../../../model/HiddenElement'
import TextElement from '@/model/TextElement' import TextElement from '../../../model/TextElement'
import TextareaElement from '@/model/TextareaElement' import TextareaElement from '../../../model/TextareaElement'
import HeadlineElement from '@/model/HeadlineElement' import HeadlineElement from '../../../model/HeadlineElement'
import Row from '@/model/Row' import MediaElement from '../../../model/MediaElement'
import SelectElement from '@/model/SelectElement' import Row from '../../../model/Row'
import { useElementStore } from '@/stores/Items' import SelectElement from '../../../model/SelectElement'
import type { PropType } from 'vue' import { useElementStore } from '../../../stores/Items'
import Parser from '@/lib/parser' import Parser from '../../../lib/parser'
import { Settings, Trash, Move, CirclePlus, Waypoints } from 'lucide-vue-next'; import { Settings, Trash, CirclePlus, Waypoints } from 'lucide-vue-next';
import { ref } from 'vue' import { ref } from 'vue'
const props = defineProps({ interface Props {
items: Array as PropType<BaseElement[]> items: BaseElement[]
}) }
defineProps<Props>()
const store = useElementStore() const store = useElementStore()
@ -111,7 +114,7 @@ const editElementDependency = (item: BaseElement) => {
/> />
<HiddenElementForm <HiddenElementForm
v-if="item.type === 1" v-if="item.type === 1"
v-model="item as InputElement" v-model="item as HiddenElement"
/> />
<SelectElementForm <SelectElementForm
v-if="item.type === 3" v-if="item.type === 3"
@ -133,6 +136,10 @@ const editElementDependency = (item: BaseElement) => {
v-if="item.type === 7" v-if="item.type === 7"
v-model="item as Row" v-model="item as Row"
/> />
<MediaElementForm
v-if="item.type === 9"
v-model="item as MediaElement"
/>
</div> </div>
<div class="buttons absolute rounded-sm invisible right-0 bg-slate-100/70 flex flex-row gap-2" v-if="!isPreview"> <div class="buttons absolute rounded-sm invisible right-0 bg-slate-100/70 flex flex-row gap-2" v-if="!isPreview">
<div v-on:click="editElementDependency(item)" class="m-2 cursor-pointer"> <div v-on:click="editElementDependency(item)" class="m-2 cursor-pointer">

View File

@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from 'vue'
import { Primitive, type PrimitiveProps } from 'reka-ui' import { Primitive, type PrimitiveProps } from 'reka-ui'
import { cn } from '@/lib/utils' import { cn } from '../../../lib/utils'
import { type ButtonVariants, buttonVariants } from '.' import { type ButtonVariants, buttonVariants } from '.'
interface Props extends PrimitiveProps { interface Props extends PrimitiveProps {

View File

@ -4,7 +4,7 @@ import type { HTMLAttributes } from 'vue'
import { reactiveOmit } from '@vueuse/core' import { reactiveOmit } from '@vueuse/core'
import { Check } from 'lucide-vue-next' import { Check } from 'lucide-vue-next'
import { CheckboxIndicator, CheckboxRoot, useForwardPropsEmits } from 'reka-ui' import { CheckboxIndicator, CheckboxRoot, useForwardPropsEmits } from 'reka-ui'
import { cn } from '@/lib/utils' import { cn } from '../../../lib/utils'
const props = defineProps<CheckboxRootProps & { class?: HTMLAttributes['class'] }>() const props = defineProps<CheckboxRootProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<CheckboxRootEmits>() const emits = defineEmits<CheckboxRootEmits>()

View File

@ -10,7 +10,7 @@ import {
DialogPortal, DialogPortal,
useForwardPropsEmits, useForwardPropsEmits,
} from 'reka-ui' } from 'reka-ui'
import { cn } from '@/lib/utils' import { cn } from '../../../lib/utils'
import DialogOverlay from './DialogOverlay.vue' import DialogOverlay from './DialogOverlay.vue'
const props = defineProps<DialogContentProps & { class?: HTMLAttributes['class'] }>() const props = defineProps<DialogContentProps & { class?: HTMLAttributes['class'] }>()

View File

@ -2,7 +2,7 @@
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from 'vue'
import { reactiveOmit } from '@vueuse/core' import { reactiveOmit } from '@vueuse/core'
import { DialogDescription, type DialogDescriptionProps, useForwardProps } from 'reka-ui' import { DialogDescription, type DialogDescriptionProps, useForwardProps } from 'reka-ui'
import { cn } from '@/lib/utils' import { cn } from '../../../lib/utils'
const props = defineProps<DialogDescriptionProps & { class?: HTMLAttributes['class'] }>() const props = defineProps<DialogDescriptionProps & { class?: HTMLAttributes['class'] }>()

View File

@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils' import { cn } from '../../../lib/utils'
const props = defineProps<{ class?: HTMLAttributes['class'] }>() const props = defineProps<{ class?: HTMLAttributes['class'] }>()
</script> </script>

View File

@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils' import { cn } from '../../../lib/utils'
const props = defineProps<{ const props = defineProps<{
class?: HTMLAttributes['class'] class?: HTMLAttributes['class']

View File

@ -2,7 +2,7 @@
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from 'vue'
import { reactiveOmit } from '@vueuse/core' import { reactiveOmit } from '@vueuse/core'
import { DialogOverlay, type DialogOverlayProps } from 'reka-ui' import { DialogOverlay, type DialogOverlayProps } from 'reka-ui'
import { cn } from '@/lib/utils' import { cn } from '../../../lib/utils'
const props = defineProps<DialogOverlayProps & { class?: HTMLAttributes['class'] }>() const props = defineProps<DialogOverlayProps & { class?: HTMLAttributes['class'] }>()

View File

@ -11,7 +11,7 @@ import {
DialogPortal, DialogPortal,
useForwardPropsEmits, useForwardPropsEmits,
} from 'reka-ui' } from 'reka-ui'
import { cn } from '@/lib/utils' import { cn } from '../../../lib/utils'
const props = defineProps<DialogContentProps & { class?: HTMLAttributes['class'] }>() const props = defineProps<DialogContentProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<DialogContentEmits>() const emits = defineEmits<DialogContentEmits>()

View File

@ -2,7 +2,7 @@
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from 'vue'
import { reactiveOmit } from '@vueuse/core' import { reactiveOmit } from '@vueuse/core'
import { DialogTitle, type DialogTitleProps, useForwardProps } from 'reka-ui' import { DialogTitle, type DialogTitleProps, useForwardProps } from 'reka-ui'
import { cn } from '@/lib/utils' import { cn } from '../../../lib/utils'
const props = defineProps<DialogTitleProps & { class?: HTMLAttributes['class'] }>() const props = defineProps<DialogTitleProps & { class?: HTMLAttributes['class'] }>()

View File

@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from 'vue'
import { useVModel } from '@vueuse/core' import { useVModel } from '@vueuse/core'
import { cn } from '@/lib/utils' import { cn } from '../../../lib/utils'
const props = defineProps<{ const props = defineProps<{
defaultValue?: string | number defaultValue?: string | number

View File

@ -2,7 +2,7 @@
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from 'vue'
import { reactiveOmit } from '@vueuse/core' import { reactiveOmit } from '@vueuse/core'
import { Label, type LabelProps } from 'reka-ui' import { Label, type LabelProps } from 'reka-ui'
import { cn } from '@/lib/utils' import { cn } from '../../../lib/utils'
const props = defineProps<LabelProps & { class?: HTMLAttributes['class'] }>() const props = defineProps<LabelProps & { class?: HTMLAttributes['class'] }>()

View File

@ -3,7 +3,7 @@ import type { HTMLAttributes } from 'vue'
import { reactiveOmit } from '@vueuse/core' import { reactiveOmit } from '@vueuse/core'
import { GripVertical } from 'lucide-vue-next' import { GripVertical } from 'lucide-vue-next'
import { SplitterResizeHandle, type SplitterResizeHandleEmits, type SplitterResizeHandleProps, useForwardPropsEmits } from 'reka-ui' import { SplitterResizeHandle, type SplitterResizeHandleEmits, type SplitterResizeHandleProps, useForwardPropsEmits } from 'reka-ui'
import { cn } from '@/lib/utils' import { cn } from '../../../lib/utils'
const props = defineProps<SplitterResizeHandleProps & { class?: HTMLAttributes['class'], withHandle?: boolean }>() const props = defineProps<SplitterResizeHandleProps & { class?: HTMLAttributes['class'], withHandle?: boolean }>()
const emits = defineEmits<SplitterResizeHandleEmits>() const emits = defineEmits<SplitterResizeHandleEmits>()

View File

@ -2,7 +2,7 @@
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from 'vue'
import { reactiveOmit } from '@vueuse/core' import { reactiveOmit } from '@vueuse/core'
import { SplitterGroup, type SplitterGroupEmits, type SplitterGroupProps, useForwardPropsEmits } from 'reka-ui' import { SplitterGroup, type SplitterGroupEmits, type SplitterGroupProps, useForwardPropsEmits } from 'reka-ui'
import { cn } from '@/lib/utils' import { cn } from '../../../lib/utils'
const props = defineProps<SplitterGroupProps & { class?: HTMLAttributes['class'] }>() const props = defineProps<SplitterGroupProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<SplitterGroupEmits>() const emits = defineEmits<SplitterGroupEmits>()

View File

@ -9,7 +9,7 @@ import {
SelectViewport, SelectViewport,
useForwardPropsEmits, useForwardPropsEmits,
} from 'reka-ui' } from 'reka-ui'
import { cn } from '@/lib/utils' import { cn } from '../../../lib/utils'
import { SelectScrollDownButton, SelectScrollUpButton } from '.' import { SelectScrollDownButton, SelectScrollUpButton } from '.'
defineOptions({ defineOptions({

View File

@ -9,7 +9,7 @@ import {
SelectItemText, SelectItemText,
useForwardProps, useForwardProps,
} from 'reka-ui' } from 'reka-ui'
import { cn } from '@/lib/utils' import { cn } from '../../../lib/utils'
const props = defineProps<SelectItemProps & { class?: HTMLAttributes['class'] }>() const props = defineProps<SelectItemProps & { class?: HTMLAttributes['class'] }>()

View File

@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from 'vue'
import { SelectLabel, type SelectLabelProps } from 'reka-ui' import { SelectLabel, type SelectLabelProps } from 'reka-ui'
import { cn } from '@/lib/utils' import { cn } from '../../../lib/utils'
const props = defineProps<SelectLabelProps & { class?: HTMLAttributes['class'] }>() const props = defineProps<SelectLabelProps & { class?: HTMLAttributes['class'] }>()
</script> </script>

View File

@ -3,7 +3,7 @@ import type { HTMLAttributes } from 'vue'
import { reactiveOmit } from '@vueuse/core' import { reactiveOmit } from '@vueuse/core'
import { ChevronDown } from 'lucide-vue-next' import { ChevronDown } from 'lucide-vue-next'
import { SelectScrollDownButton, type SelectScrollDownButtonProps, useForwardProps } from 'reka-ui' import { SelectScrollDownButton, type SelectScrollDownButtonProps, useForwardProps } from 'reka-ui'
import { cn } from '@/lib/utils' import { cn } from '../../../lib/utils'
const props = defineProps<SelectScrollDownButtonProps & { class?: HTMLAttributes['class'] }>() const props = defineProps<SelectScrollDownButtonProps & { class?: HTMLAttributes['class'] }>()

View File

@ -3,7 +3,7 @@ import type { HTMLAttributes } from 'vue'
import { reactiveOmit } from '@vueuse/core' import { reactiveOmit } from '@vueuse/core'
import { ChevronUp } from 'lucide-vue-next' import { ChevronUp } from 'lucide-vue-next'
import { SelectScrollUpButton, type SelectScrollUpButtonProps, useForwardProps } from 'reka-ui' import { SelectScrollUpButton, type SelectScrollUpButtonProps, useForwardProps } from 'reka-ui'
import { cn } from '@/lib/utils' import { cn } from '../../../lib/utils'
const props = defineProps<SelectScrollUpButtonProps & { class?: HTMLAttributes['class'] }>() const props = defineProps<SelectScrollUpButtonProps & { class?: HTMLAttributes['class'] }>()

View File

@ -2,7 +2,7 @@
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from 'vue'
import { reactiveOmit } from '@vueuse/core' import { reactiveOmit } from '@vueuse/core'
import { SelectSeparator, type SelectSeparatorProps } from 'reka-ui' import { SelectSeparator, type SelectSeparatorProps } from 'reka-ui'
import { cn } from '@/lib/utils' import { cn } from '../../../lib/utils'
const props = defineProps<SelectSeparatorProps & { class?: HTMLAttributes['class'] }>() const props = defineProps<SelectSeparatorProps & { class?: HTMLAttributes['class'] }>()

View File

@ -3,7 +3,7 @@ import type { HTMLAttributes } from 'vue'
import { reactiveOmit } from '@vueuse/core' import { reactiveOmit } from '@vueuse/core'
import { ChevronDown } from 'lucide-vue-next' import { ChevronDown } from 'lucide-vue-next'
import { SelectIcon, SelectTrigger, type SelectTriggerProps, useForwardProps } from 'reka-ui' import { SelectIcon, SelectTrigger, type SelectTriggerProps, useForwardProps } from 'reka-ui'
import { cn } from '@/lib/utils' import { cn } from '../../../lib/utils'
const props = withDefaults( const props = withDefaults(
defineProps<SelectTriggerProps & { class?: HTMLAttributes['class'], size?: 'sm' | 'default' }>(), defineProps<SelectTriggerProps & { class?: HTMLAttributes['class'], size?: 'sm' | 'default' }>(),

View File

@ -10,7 +10,7 @@ import {
DialogPortal, DialogPortal,
useForwardPropsEmits, useForwardPropsEmits,
} from 'reka-ui' } from 'reka-ui'
import { cn } from '@/lib/utils' import { cn } from '../../../lib/utils'
import SheetOverlay from './SheetOverlay.vue' import SheetOverlay from './SheetOverlay.vue'
interface SheetContentProps extends DialogContentProps { interface SheetContentProps extends DialogContentProps {

View File

@ -2,7 +2,7 @@
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from 'vue'
import { reactiveOmit } from '@vueuse/core' import { reactiveOmit } from '@vueuse/core'
import { DialogDescription, type DialogDescriptionProps } from 'reka-ui' import { DialogDescription, type DialogDescriptionProps } from 'reka-ui'
import { cn } from '@/lib/utils' import { cn } from '../../../lib/utils'
const props = defineProps<DialogDescriptionProps & { class?: HTMLAttributes['class'] }>() const props = defineProps<DialogDescriptionProps & { class?: HTMLAttributes['class'] }>()

View File

@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils' import { cn } from '../../../lib/utils'
const props = defineProps<{ class?: HTMLAttributes['class'] }>() const props = defineProps<{ class?: HTMLAttributes['class'] }>()
</script> </script>

View File

@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils' import { cn } from '../../../lib/utils'
const props = defineProps<{ class?: HTMLAttributes['class'] }>() const props = defineProps<{ class?: HTMLAttributes['class'] }>()
</script> </script>

View File

@ -2,7 +2,7 @@
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from 'vue'
import { reactiveOmit } from '@vueuse/core' import { reactiveOmit } from '@vueuse/core'
import { DialogOverlay, type DialogOverlayProps } from 'reka-ui' import { DialogOverlay, type DialogOverlayProps } from 'reka-ui'
import { cn } from '@/lib/utils' import { cn } from '../../../lib/utils'
const props = defineProps<DialogOverlayProps & { class?: HTMLAttributes['class'] }>() const props = defineProps<DialogOverlayProps & { class?: HTMLAttributes['class'] }>()

View File

@ -2,7 +2,7 @@
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from 'vue'
import { reactiveOmit } from '@vueuse/core' import { reactiveOmit } from '@vueuse/core'
import { DialogTitle, type DialogTitleProps } from 'reka-ui' import { DialogTitle, type DialogTitleProps } from 'reka-ui'
import { cn } from '@/lib/utils' import { cn } from '../../../lib/utils'
const props = defineProps<DialogTitleProps & { class?: HTMLAttributes['class'] }>() const props = defineProps<DialogTitleProps & { class?: HTMLAttributes['class'] }>()

View File

@ -8,7 +8,7 @@ import {
SwitchThumb, SwitchThumb,
useForwardPropsEmits, useForwardPropsEmits,
} from 'reka-ui' } from 'reka-ui'
import { cn } from '@/lib/utils' import { cn } from '../../../lib/utils'
const props = defineProps<SwitchRootProps & { class?: HTMLAttributes['class'] }>() const props = defineProps<SwitchRootProps & { class?: HTMLAttributes['class'] }>()

View File

@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HTMLAttributes } from 'vue' import type { HTMLAttributes } from 'vue'
import { useVModel } from '@vueuse/core' import { useVModel } from '@vueuse/core'
import { cn } from '@/lib/utils' import { cn } from '../../../lib/utils'
const props = defineProps<{ const props = defineProps<{
class?: HTMLAttributes['class'] class?: HTMLAttributes['class']

View File

@ -0,0 +1,28 @@
import { ref, onMounted } from 'vue'
import api from '../lib/api'
interface Media {
id: number
title: string
}
export function useMedia() {
const media = ref<Media[]>([])
const loading = ref(false)
const error = ref<unknown>(null)
const fetchMedia = async () => {
loading.value = true
try {
media.value = await api.get('api/plugins/media').json<Media[]>()
} catch (err) {
error.value = err
} finally {
loading.value = false;
}
}
onMounted(fetchMedia)
return { media, loading, error, fetchMedia }
}

View File

@ -0,0 +1,22 @@
import ky from 'ky';
const api = ky.create({
prefixUrl: 'apps',
headers: {
'Content-Type': 'application/json',
},
timeout: 10000,
hooks: {
beforeRequest: [
request => {
// Optional: Token aus Storage holen
const token = localStorage.getItem('token');
if (token) {
request.headers.set('Authorization', `Bearer ${token}`);
}
},
],
},
});
export default api;

View File

@ -1,6 +1,7 @@
import type BaseElement from "../model/BaseElement" import type BaseElement from "../model/BaseElement"
import InputElement from "../model/InputElement" import InputElement from "../model/InputElement"
import Row from "../model/Row" import Row from "../model/Row"
import MediaElement from "../model/MediaElement"
import Column from "../model/Column" import Column from "../model/Column"
import HiddenElement from "../model/HiddenElement" import HiddenElement from "../model/HiddenElement"
import SelectElement from "../model/SelectElement" import SelectElement from "../model/SelectElement"
@ -12,6 +13,8 @@ export default class Parser {
static getModelForType(type: Number) : BaseElement { static getModelForType(type: Number) : BaseElement {
switch(type) { switch(type) {
case 9:
return new MediaElement
case 8: case 8:
return new Column return new Column
case 7: case 7:

View File

@ -6,7 +6,10 @@ export enum ElementType {
InputElement = 2, InputElement = 2,
SelectElement = 3, SelectElement = 3,
EMailElement = 4, EMailElement = 4,
Column2Element = 10 TextareaElement = 5,
HeadlineElement = 6,
Column = 8,
Row = 7
} }
export default class BaseElement { export default class BaseElement {
@ -20,17 +23,17 @@ export default class BaseElement {
return { return {
'id': this.id, 'id': this.id,
'type': this.type, 'type': this.type,
'dependencys': this.dependencys.reduce((result, dep) => { 'dependencys': this.dependencys.reduce((result: object[], dep: Dependency) => {
result.push(dep.toJSON()) result.push(dep.toJSON())
return result return result
}, []) }, [])
} }
} }
fromJSON(obj) { fromJSON(obj: any) {
this.id = obj.id this.id = obj.id
this.type = obj.type this.type = obj.type
obj.dependencys.map((d) => { obj.dependencys.map((d: any) => {
const dep = new Dependency() const dep = new Dependency()
dep.fromJSON(d) dep.fromJSON(d)
this.dependencys.push(dep) this.dependencys.push(dep)
@ -50,7 +53,7 @@ export default class BaseElement {
} }
} }
addDependency(dep: Dependeny) addDependency(dep: Dependency)
{ {
this.dependencys.push(dep) this.dependencys.push(dep)
} }
@ -59,18 +62,11 @@ export default class BaseElement {
return false return false
} }
insertItemInEmptyColumn(item: BaseElement, targetUuid: string, column: Number) {
return false
}
cutItem(existingUuid: string) { cutItem(existingUuid: string) {
return null return null
} }
getItem(existingUuid: string) { deleteItem(item: BaseElement): boolean {
return null return false
}
deleteItem(item: BaseElement) {
} }
} }

View File

@ -23,7 +23,7 @@ export default class Border {
this.uuid = uuidv4(); this.uuid = uuidv4();
} }
addDependency(dep: Dependeny) addDependency(dep: Dependency)
{ {
this.dependencys.push(dep) this.dependencys.push(dep)
} }
@ -44,13 +44,13 @@ export default class Border {
'calcValue10': this.calcValue10, 'calcValue10': this.calcValue10,
'flatRate': this.flatRate, 'flatRate': this.flatRate,
'value': this.value, 'value': this.value,
'dependencys': this.dependencys.reduce((result, dep) => { 'dependencys': this.dependencys.reduce((result: object[], dep: Dependency) => {
result.push(dep.toJSON()) result.push(dep.toJSON())
return result return result
}, []) }, [])
} }
} }
fromJSON(obj) { fromJSON(obj: any) {
this.formula = obj.formula this.formula = obj.formula
this.value = obj.value this.value = obj.value
this.flatRate = obj.flatRate this.flatRate = obj.flatRate
@ -65,7 +65,7 @@ export default class Border {
this.calcValue8 = obj.calcValue8 this.calcValue8 = obj.calcValue8
this.calcValue9 = obj.calcValue9 this.calcValue9 = obj.calcValue9
this.calcValue10 = obj.calcValue10 this.calcValue10 = obj.calcValue10
obj.dependencys.map((d) => { obj.dependencys.map((d: any) => {
const dep = new Dependency() const dep = new Dependency()
dep.fromJSON(d) dep.fromJSON(d)
this.dependencys.push(dep) this.dependencys.push(dep)

View File

@ -16,38 +16,25 @@ export default class Column extends BaseElement {
return Object.assign( return Object.assign(
super.toJSON(), super.toJSON(),
{ {
'items': this.items.reduce((result, item) => { 'items': this.items.reduce((result: object[], item: BaseElement) => {
result.push(item.toJSON()) result.push(item.toJSON())
return result return result
}, []) }, [])
}) })
} }
fromJSON(obj) { fromJSON(obj: any) {
super.fromJSON(obj) super.fromJSON(obj)
obj.columns.map((d) => { obj.columns.map((d: any) => {
const column = new Column() const column = new Column()
column.fromJSON(d) column.fromJSON(d)
this.columns.push(column) this.items.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) { cutItem(existingUuid: string) {
let item: BaseElement|null = null; let item: BaseElement|null = null;
this.items.forEach((element,indexArray) => { this.items.forEach((element: BaseElement,indexArray: number) => {
if(element.uuid === existingUuid) { if(element.uuid === existingUuid) {
item = this.items.splice(indexArray, 1)[0] item = this.items.splice(indexArray, 1)[0]
return true return true
@ -76,7 +63,7 @@ export default class Column extends BaseElement {
} }
deleteItem(item: BaseElement): boolean { deleteItem(item: BaseElement): boolean {
return this.items.some((element,indexArray) => { return this.items.some((element: BaseElement,indexArray: number) => {
if(element.uuid === item.uuid) { if(element.uuid === item.uuid) {
item = this.items.splice(indexArray, 1)[0] item = this.items.splice(indexArray, 1)[0]
return true return true

View File

@ -20,17 +20,17 @@ export default class Dependency {
return { return {
'formula': this.formula, 'formula': this.formula,
'relation': this.relation, 'relation': this.relation,
'borders': this.borders.reduce((result, border) => { 'borders': this.borders.reduce((result: object[], border: Border) => {
result.push(border.toJSON()) result.push(border.toJSON())
return result return result
}, []) }, [])
} }
} }
fromJSON(obj) { fromJSON(obj: any) {
this.relation = obj.relation this.relation = obj.relation
this.formula = obj.formula this.formula = obj.formula
obj.borders.map((b) => { obj.borders.map((b: any) => {
const border = new Border() const border = new Border()
border.fromJSON(b) border.fromJSON(b)
this.borders.push(border) this.borders.push(border)

View File

@ -22,7 +22,7 @@ export default class HeadlineElement extends BaseElement {
}) })
} }
fromJSON(obj) { fromJSON(obj: any) {
super.fromJSON(obj) super.fromJSON(obj)
this.name = obj.name this.name = obj.name
this.default = obj.default this.default = obj.default

View File

@ -20,7 +20,7 @@ export default class HiddenElement extends BaseElement {
}) })
} }
fromJSON(obj) { fromJSON(obj: any) {
super.fromJSON(obj) super.fromJSON(obj)
this.name = obj.name this.name = obj.name
this.default = obj.default this.default = obj.default

View File

@ -2,12 +2,12 @@ import BaseElement from "./BaseElement";
export default class InputElement extends BaseElement { export default class InputElement extends BaseElement {
default: string = "" default: string = ""
placeholder: string = "Placeholder" placeHolder: string = "Placeholder"
required: boolean = false required: boolean = false
name: string = "" name: string = ""
xmlType: string = "input" xmlType: string = "input"
minValue: int = 0 minValue: number = 0
maxValue: int = 0 maxValue: number = 0
constructor() { constructor() {
super(); super();
@ -18,7 +18,7 @@ export default class InputElement extends BaseElement {
return Object.assign( return Object.assign(
super.toJSON(), super.toJSON(),
{ {
'placeHolder': this.placeholder, 'placeHolder': this.placeHolder,
'default': this.default, 'default': this.default,
'name': this.name, 'name': this.name,
'minValue': this.minValue, 'minValue': this.minValue,
@ -27,7 +27,7 @@ export default class InputElement extends BaseElement {
}) })
} }
fromJSON(obj) { fromJSON(obj: any) {
super.fromJSON(obj) super.fromJSON(obj)
this.name = obj.name this.name = obj.name
this.default = obj.default this.default = obj.default

View File

@ -7,7 +7,7 @@ export default class MediaElement extends BaseElement {
constructor() { constructor() {
super(); super();
this.type = 8 this.type = 9
} }
public toJSON() { public toJSON() {
@ -19,7 +19,7 @@ export default class MediaElement extends BaseElement {
}) })
} }
fromJSON(obj) { fromJSON(obj: any) {
super.fromJSON(obj) super.fromJSON(obj)
this.name = obj.name this.name = obj.name
this.default = obj.default this.default = obj.default

View File

@ -17,7 +17,7 @@ export default class Row extends BaseElement {
return Object.assign( return Object.assign(
super.toJSON(), super.toJSON(),
{ {
'columns': this.columns.reduce((result, column) => { 'columns': this.columns.reduce((result: object[], column: Column) => {
result.push(column.toJSON()) result.push(column.toJSON())
return result return result
}, []) }, [])
@ -26,7 +26,7 @@ export default class Row extends BaseElement {
cutItem(existingUuid: string) { cutItem(existingUuid: string) {
let item: BaseElement|null = null; let item: BaseElement|null = null;
this.columns.some((col,indexArray) => { this.columns.some((col: Column) => {
item = col.cutItem(existingUuid) item = col.cutItem(existingUuid)
if(item !== null) { if(item !== null) {
return true return true
@ -35,20 +35,8 @@ export default class Row extends BaseElement {
return item 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 { insertItem(item: BaseElement, targetUuid: string): boolean {
this.columns.some((col,indexArray) => { this.columns.some((col: Column) => {
if(col.insertItem(item, targetUuid)) { if(col.insertItem(item, targetUuid)) {
return true; return true;
} }
@ -57,7 +45,7 @@ export default class Row extends BaseElement {
} }
deleteItem(item: BaseElement): boolean { deleteItem(item: BaseElement): boolean {
this.columns.some((col,indexArray) => { this.columns.some((col: Column) => {
if(col.deleteItem(item)) { if(col.deleteItem(item)) {
return true; return true;
} }
@ -72,9 +60,9 @@ export default class Row extends BaseElement {
return false return false
} }
fromJSON(obj) { fromJSON(obj: any) {
super.fromJSON(obj) super.fromJSON(obj)
obj.columns.map((d) => { obj.columns.map((d: any) => {
const column = new Column() const column = new Column()
column.fromJSON(d) column.fromJSON(d)
this.columns.push(column) this.columns.push(column)

View File

@ -13,7 +13,7 @@ export default class SelectElement extends BaseElement {
this.type = 3 this.type = 3
} }
addOption(option: SelectElementOption) { addOption(option: Option) {
this.options.push(option) this.options.push(option)
} }
@ -24,7 +24,7 @@ export default class SelectElement extends BaseElement {
'default': this.default, 'default': this.default,
'mode': this.mode, 'mode': this.mode,
'container': this.container, 'container': this.container,
'options': this.options.reduce((result, opt) => { 'options': this.options.reduce((result: object[], opt: Option) => {
result.push(opt.toJSON()) result.push(opt.toJSON())
return result return result
}, []), }, []),
@ -32,14 +32,14 @@ export default class SelectElement extends BaseElement {
}) })
} }
fromJSON(obj) { fromJSON(obj: any) {
super.fromJSON(obj) super.fromJSON(obj)
this.name = obj.name this.name = obj.name
this.mode = obj.mode this.mode = obj.mode
this.container = obj.container this.container = obj.container
this.default = obj.default this.default = obj.default
obj.options.map((d) => { obj.options.map((d: any) => {
const option = new Option() const option = new Option("")
option.fromJSON(d) option.fromJSON(d)
this.options.push(option) this.options.push(option)
}) })

View File

@ -20,7 +20,7 @@ export default class TextElement extends BaseElement {
}) })
} }
fromJSON(obj) { fromJSON(obj: any) {
super.fromJSON(obj) super.fromJSON(obj)
this.name = obj.name this.name = obj.name
this.default = obj.default this.default = obj.default

View File

@ -19,7 +19,7 @@ export default class TextareaElement extends BaseElement {
}) })
} }
fromJSON(obj) { fromJSON(obj: any) {
super.fromJSON(obj) super.fromJSON(obj)
this.name = obj.name this.name = obj.name
this.default = obj.default this.default = obj.default

View File

@ -13,7 +13,7 @@ export default class Option {
this.id = id; this.id = id;
} }
addDependency(dep: Dependeny) addDependency(dep: Dependency)
{ {
this.dependencys.push(dep) this.dependencys.push(dep)
} }
@ -22,17 +22,17 @@ export default class Option {
return { return {
'id': this.id, 'id': this.id,
'name': this.name, 'name': this.name,
'dependencys': this.dependencys.reduce((result, dep) => { 'dependencys': this.dependencys.reduce((result: object[], dep: Dependency) => {
result.push(dep.toJSON()) result.push(dep.toJSON())
return result return result
}, []) }, [])
} }
} }
fromJSON(obj) { fromJSON(obj: any) {
this.name = obj.name this.name = obj.name
this.id = obj.id this.id = obj.id
obj.dependencys.map((d) => { obj.dependencys.map((d: any) => {
const dep = new Dependency() const dep = new Dependency()
dep.fromJSON(d) dep.fromJSON(d)
this.dependencys.push(dep) this.dependencys.push(dep)

View File

@ -1,7 +1,6 @@
import { ref, computed } from 'vue'
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import BaseElement from '@/model/BaseElement' import BaseElement from '../model/BaseElement'
import Parser from '@/lib/parser' import Parser from '../lib/parser'
import {v4 as uuidv4} from 'uuid' import {v4 as uuidv4} from 'uuid'
export const useElementStore = defineStore('items', { export const useElementStore = defineStore('items', {
@ -32,7 +31,7 @@ export const useElementStore = defineStore('items', {
this.items.push(item) this.items.push(item)
}, },
loadJSON() { loadJSON() {
let options: [] = this.items.reduce((result, opt) => { let options: object[] = this.items.reduce((result: object[], opt: BaseElement) => {
result.push(opt.toJSON()) result.push(opt.toJSON())
return result return result
}, []) }, [])
@ -52,19 +51,19 @@ export const useElementStore = defineStore('items', {
if(obj[0].uuid) { if(obj[0].uuid) {
this.uuid = obj[0].uuid this.uuid = obj[0].uuid
} }
obj[0].options.map((ob) => { obj[0].options.map((ob: any) => {
const item = Parser.getModelForType(ob.type) const item = Parser.getModelForType(ob.type)
item.fromJSON(ob) item.fromJSON(ob)
this.addElement(item) this.addElement(item)
}) })
}, },
changeFocus(uuid: string) { changeFocus(uuid: string) {
this.items.forEach(element => { this.items.forEach((element: BaseElement) => {
element.changeFocus(uuid) element.changeFocus(uuid)
}) })
}, },
clearSelection() { clearSelection() {
this.items.forEach(element => { this.items.forEach((element: BaseElement) => {
element.changeFocus("xx") element.changeFocus("xx")
}) })
this.showProperties = false this.showProperties = false
@ -81,8 +80,8 @@ export const useElementStore = defineStore('items', {
setActiveItem(item: BaseElement) { setActiveItem(item: BaseElement) {
this.activeItem = item this.activeItem = item
}, },
deleteItem(item: BaseElement) { deleteItem(item: BaseElement): boolean {
return this.items.some((element,indexArray) => { return this.items.some((element: BaseElement,indexArray: number) => {
if(element.uuid === item.uuid) { if(element.uuid === item.uuid) {
item = this.items.splice(indexArray, 1)[0] item = this.items.splice(indexArray, 1)[0]
return true return true
@ -92,14 +91,12 @@ export const useElementStore = defineStore('items', {
} }
}) })
}, },
moveSortItemToEmptyElement(targetUuid: string, column: Column) {
const item = this.cutItem(this.sourceDragUuid)
this.insertItemInEmptyColumn(this.items, item!, targetUuid, column)
},
moveItemBefore(dragUuid: string, targetUuid: string): boolean { moveItemBefore(dragUuid: string, targetUuid: string): boolean {
const item = this.cutItem(dragUuid) const item = this.cutItem(dragUuid)
return this.insertItem(this.items, item, targetUuid) if(item) {
return this.insertItem(this.items, item, targetUuid)
}
return false
}, },
addElementAfter(item: BaseElement, targetUuid: string) { addElementAfter(item: BaseElement, targetUuid: string) {
this.insertItem(this.items, item, targetUuid) this.insertItem(this.items, item, targetUuid)
@ -109,7 +106,7 @@ export const useElementStore = defineStore('items', {
}, },
cutItem(existingUuid: string) { cutItem(existingUuid: string) {
let item: BaseElement|null = null let item: BaseElement|null = null
this.items.some((element,indexArray) => { this.items.some((element: BaseElement,indexArray: number) => {
if(element.uuid === existingUuid) { if(element.uuid === existingUuid) {
item = this.items.splice(indexArray, 1)[0] item = this.items.splice(indexArray, 1)[0]
return true return true
@ -123,22 +120,6 @@ export const useElementStore = defineStore('items', {
}) })
return item 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
}
}
})
return item
},
insertItem(items: BaseElement[], item: BaseElement, targetUuid: string): boolean { insertItem(items: BaseElement[], item: BaseElement, targetUuid: string): boolean {
let inserted = false let inserted = false
for (let i = 0; i < items.length; ++i) { for (let i = 0; i < items.length; ++i) {
@ -154,15 +135,6 @@ export const useElementStore = defineStore('items', {
return inserted return inserted
}, },
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)
}
return inserted
},
setDragMode(mode: string) { setDragMode(mode: string) {
this.dragMode = mode this.dragMode = mode
} }

View File

@ -6,16 +6,17 @@
/* Linting */ /* Linting */
"strict": true, "strict": true,
"noUnusedLocals": true, "noUnusedLocals": true,
"noUnusedParameters": true, "noUnusedParameters": false,
"erasableSyntaxOnly": true, "erasableSyntaxOnly": false,
"noFallthroughCasesInSwitch": true, "noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true "noUncheckedSideEffectImports": true
}, },
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"], "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"],
"baseUrl": ".", "baseUrl": ".",
"paths": { "paths": {
"@/lib*": ["./src/lib/*"],
"@/*": [ "@/*": [
"./src/*" "./src/*",
] ]
} }
} }

View File

@ -6,6 +6,17 @@ import vueDevTools from 'vite-plugin-vue-devtools'
export default defineConfig({ export default defineConfig({
plugins: [vueDevTools(), vue(), tailwindcss()], plugins: [vueDevTools(), vue(), tailwindcss()],
build: {
rollupOptions: {
output: {
entryFileNames: `assets/[name].js`,
chunkFileNames: `assets/[name].js`,
assetFileNames: `assets/[name].[ext]`
}
},
outDir: '../Resources/public/formbuilderts',
emptyOutDir: true, // also necessary
},
resolve: { resolve: {
alias: { alias: {
'@': path.resolve(__dirname, './src'), '@': path.resolve(__dirname, './src'),

View File

@ -0,0 +1,6 @@
psc_backend_component_formbuilder:
resource: "@PluginCustomPSCFormBuilder/Controller/Backend"
type: annotation
prefix: /backend/component/formbuilder

View File

@ -0,0 +1,11 @@
services:
_defaults:
autowire: true
autoconfigure: true
Plugin\Custom\PSC\FormBuilder\:
resource: '../../*/*'
# Plugin\System\PSC\Invoice\Section\Invoice:
# tags:
# - { name: psc.backend.custom.section }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,14 @@
<!doctype html>
<html lang="en">
<head>
<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>Calc</title>
<script type="module" crossorigin src="/assets/index.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index.css">
</head>
<body>
<div id="app" class="w-screen h-screen"></div>
</body>
</html>

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="de-DE">
<head>
<meta charset="utf-8">
<title>PSC FormBuilder</title>
<meta name="description" content="">
<meta name="author" content="">
<base href="/apps/backend/component/formbuilder/index/create/"/>
<link rel="stylesheet" href="/apps/bundles/plugincustompscformbuilder/formbuilderts/assets/index.css"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
{% block stylesheets %}
{% endblock %}
</head>
<body>
<main id="app"></main>
{% block javascripts %}
<script>
var jwt_token = '{{ jwt }}';
</script>
<script src="/apps/bundles/plugincustompscformbuilder/formbuilderts/assets/index.js"></script>
{% endblock %}
</body>
</html>

View File

@ -0,0 +1,7 @@
{% if uuid %}
<a href="/apps/backend/component/invoice/index/create#/{{ uuid }}" target="_blank" class="btn btn-warning btn-sm">Auftrag bearbeiten (BETA)</a>
{% else %}
<div class="panel">
<div class="body"><a href="/apps/backend/component/invoice/index/create" target="_blank" class="btn btn-warning btn-sm">Auftrag anlegen (BETA)</a></div>
</div>
{% endif %}

View File

@ -35,12 +35,33 @@ if ($teile[5] == "") {
productUUId = '<?php echo $this->article->uuid ?>'; productUUId = '<?php echo $this->article->uuid ?>';
productLoaded = <?php echo ($this->load) ? 1 : 0 ?>; productLoaded = <?php echo ($this->load) ? 1 : 0 ?>;
productUrl = '<?php echo $this->article->url ?>'; productUrl = '<?php echo $this->article->url ?>';
productValues = new Map();
<?php
if ($this->load || $this->rebuy) {
foreach (TP_Basket::getBasket()->getTempProduct($this->article->uuid)->getAdditionalInfo('saxoprint')['infos'] as $var) {
echo "productValues.set('" . $var['name'] . "', '" . $var['value'] . "');";
}
}
?>
$(document).ready(function(){ $(document).ready(function(){
var saxoprint = new Saxoprint("<?php echo $this->article->uuid; ?>", "<?php echo $this->article->getPluginSettings('saxoprint', 'saxoprint'); ?>", "<?php echo $this->article->getPluginSettings('saxoprint', 'saxoprintauflage'); ?>", <?php echo $this->article->mwert ?>) var saxoprint = new Saxoprint("<?php echo $this->article->uuid; ?>", "<?php echo $this->article->getPluginSettings('saxoprint', 'saxoprint'); ?>", "<?php echo $this->article->getPluginSettings('saxoprint', 'saxoprintauflage'); ?>", <?php echo $this->article->mwert ?>)
saxoprint.init(); saxoprint.init();
}); });
window.onload = function() { window.onload = function() {
<?php
if ($this->load || $this->rebuy) {
echo 'document.getElementById("upload_mode").value = "' . TP_Basket::getBasket()->getTempProduct($this->article->uuid)->getUploadMode() . '";';
}
if($this->layouterSession) {
echo 'document.getElementById("upload_mode").value = "' . $this->layouterSession->layouter_modus . '";';
}
?>
<?php if ($backlink == "") { ?> <?php if ($backlink == "") { ?>
$("#breadcrumbs-Article").attr("href", "/overview/") $("#breadcrumbs-Article").attr("href", "/overview/")
<?php } else { ?> <?php } else { ?>
@ -630,6 +651,7 @@ if ($teile[5] == "") {
<?php if (!$this->article->not_buy) : ?> <?php if (!$this->article->not_buy) : ?>
<form action="/article/buy/?id=<?= $this->article->id ?>" target="_self" class="buy" role="form" id="buyform" method="POST"> <form action="/article/buy/?id=<?= $this->article->id ?>" target="_self" class="buy" role="form" id="buyform" method="POST">
<input type="hidden" value="1" name="count"> <input type="hidden" value="1" name="count">
<?= $this->formHidden('load', $this->load) ?>
<input type="hidden" id="upload_mode" name="upload_mode" value="<?php echo $this->upload_mode ?>" /> <input type="hidden" id="upload_mode" name="upload_mode" value="<?php echo $this->upload_mode ?>" />
<input type="hidden" value="" name="collecting_orders_data" id="collecting_orders_data"/> <input type="hidden" value="" name="collecting_orders_data" id="collecting_orders_data"/>
<input type="submit" id="in_basket" class="btn btn-success btn-large" value="Bestellen"/> <input type="submit" id="in_basket" class="btn btn-success btn-large" value="Bestellen"/>

View File

@ -5,8 +5,28 @@ $this->headScript()->prependFile('/'. $this->designPath . '/js/saxoprint.js');
productUUId = '<?php echo $this->article->uuid ?>'; productUUId = '<?php echo $this->article->uuid ?>';
productLoaded = <?php echo ($this->load) ? 1 : 0 ?>; productLoaded = <?php echo ($this->load) ? 1 : 0 ?>;
productUrl = '<?php echo $this->article->url ?>'; productUrl = '<?php echo $this->article->url ?>';
productValues = new Map();
<?php
if ($this->load || $this->rebuy) {
foreach (TP_Basket::getBasket()->getTempProduct($this->article->uuid)->getAdditionalInfo('saxoprint')['infos'] as $var) {
echo "productValues.set('" . $var['name'] . "', '" . $var['value'] . "');";
}
}
?>
window.onload = function() { window.onload = function() {
<?php
if ($this->load || $this->rebuy) {
echo 'document.getElementById("upload_mode").value = "' . TP_Basket::getBasket()->getTempProduct($this->article->uuid)->getUploadMode() . '";';
}
if($this->layouterSession) {
echo 'document.getElementById("upload_mode").value = "' . $this->layouterSession->layouter_modus . '";';
}
?>
$('#in_basket').removeClass('disabled'); $('#in_basket').removeClass('disabled');
var saxoprint = new Saxoprint("<?php echo $this->article->uuid; ?>", "<?php echo $this->article->getPluginSettings('saxoprint', 'saxoprint'); ?>", "<?php echo $this->article->getPluginSettings('saxoprint', 'saxoprintauflage'); ?>", <?php echo $this->article->mwert ?>) var saxoprint = new Saxoprint("<?php echo $this->article->uuid; ?>", "<?php echo $this->article->getPluginSettings('saxoprint', 'saxoprint'); ?>", "<?php echo $this->article->getPluginSettings('saxoprint', 'saxoprintauflage'); ?>", <?php echo $this->article->mwert ?>)
saxoprint.init(); saxoprint.init();
@ -14,26 +34,7 @@ $this->headScript()->prependFile('/'. $this->designPath . '/js/saxoprint.js');
</script> </script>
<!--
<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">
<?php if ($this->article->file != "" && $this->layouterPreviewId == "") : ?>
<?php echo $this->image()->thumbnailImage($this->article->title, 'productdetail', $this->article->file); ?>
<?php endif; ?>
</div>
<div class="md:w-1/2">
<h2 class="text-highlight text-2xl font-lenzFont"><?php echo $this->article->title ?></h2>
<p><?php echo $this->article->einleitung ?></p>
</div>
</div>
-->
<div class="mt-10 md:m-auto ml-2 mr-2"> <div class="mt-10 md:m-auto ml-2 mr-2">
<!--
<div class="bg-gray-200 divide-x flex w-full" id="default-tab" data-tabs-active-classes="border-b-2 border-gray-400 bg-gray-300" data-tabs-toggle="#product-content" role="tablist">
<div class="w-1/2 p-1 cursor-pointer" data-tabs-target="#div-calc" type="button" role="tab" aria-controls="div-calc" aria-selected="false">Kalkulation</div>
<div class="w-1/2 p-1 cursor-pointer" data-tabs-target="#div-details" type="button" role="tab" aria-controls="div-details" aria-selected="false">Beschreibung</div>
</div>
-->
<div id="product-content"> <div id="product-content">
<div id="div-calc" role="tabpanel" aria-labelledby="div-calc-tab"> <div id="div-calc" role="tabpanel" aria-labelledby="div-calc-tab">
<div class="md:flex"> <div class="md:flex">
@ -63,6 +64,7 @@ $this->headScript()->prependFile('/'. $this->designPath . '/js/saxoprint.js');
<?php if (!$this->article->not_buy) : ?> <?php if (!$this->article->not_buy) : ?>
<form action="/article/buy/?id=<?= $this->article->id ?>" target="_self" class="buy" role="form" id="buyform" method="POST"> <form action="/article/buy/?id=<?= $this->article->id ?>" target="_self" class="buy" role="form" id="buyform" method="POST">
<input type="hidden" value="1" name="count"> <input type="hidden" value="1" name="count">
<?= $this->formHidden('load', $this->load) ?>
<input type="hidden" id="upload_mode" name="upload_mode" value="<?php echo $this->upload_mode ?>" /> <input type="hidden" id="upload_mode" name="upload_mode" value="<?php echo $this->upload_mode ?>" />
<input type="hidden" value="" name="collecting_orders_data" id="collecting_orders_data"/> <input type="hidden" value="" name="collecting_orders_data" id="collecting_orders_data"/>
<button type="submit" id="in_basket" class="w-full transition ease-in-out duration-300 delay-150 hover:bg-white hover:text-black border-slate-200 border bg-highlight text-white p-2 pl-5 pr-5 rounded-full disabled bg-highlight "><?= $this->translate('Buy') ?></button> <button type="submit" id="in_basket" class="w-full transition ease-in-out duration-300 delay-150 hover:bg-white hover:text-black border-slate-200 border bg-highlight text-white p-2 pl-5 pr-5 rounded-full disabled bg-highlight "><?= $this->translate('Buy') ?></button>

View File

@ -13,26 +13,22 @@
foreach (TP_Basket::getBasket()->getTempProduct($this->article->uuid)->getOptions() as $key => $var) { foreach (TP_Basket::getBasket()->getTempProduct($this->article->uuid)->getOptions() as $key => $var) {
echo "productValues['" . $key . "'] = '" . $var . "';"; echo "productValues['" . $key . "'] = '" . $var . "';";
} }
echo '$("#upload_mode").val("' . TP_Basket::getBasket()->getTempProduct($this->article->uuid)->getUploadMode() . '");';
} }
if($this->layouterSession) {
echo '$("#upload_mode").val("' . $this->layouterSession->layouter_modus . '");';
}
?> ?>
window.onload = function() { window.onload = function() {
<?php <?php
if ($this->load || $this->rebuy) { if ($this->load || $this->rebuy) {
echo '$("#upload_mode").val("' . TP_Basket::getBasket()->getTempProduct($this->article->uuid)->getUploadMode() . '");'; echo 'document.getElementById("upload_mode").value = "' . TP_Basket::getBasket()->getTempProduct($this->article->uuid)->getUploadMode() . '";';
} }
if($this->layouterSession) { if($this->layouterSession) {
echo '$("#upload_mode").val("' . $this->layouterSession->layouter_modus . '");'; echo 'document.getElementById("upload_mode").value = "' . $this->layouterSession->layouter_modus . '";';
} }
?> ?>
$('#in_basket').removeClass('disabled');
} }
</script> </script>

View File

@ -727,6 +727,12 @@ class TP_Basket_Item
return $this->_additionalInfos; return $this->_additionalInfos;
} }
public function getAdditionalInfo(string $key)
{
return array_find($this->_additionalInfos, fn($element) => $element['key'] == $key);
}
/** /**
* @param array $additionalInfos * @param array $additionalInfos
*/ */

View File

@ -6,6 +6,7 @@ class Saxoprint {
price = 0 price = 0
options = [] options = []
info = [] info = []
firstLoad = true
constructor(productId, saxoprintProductId, auflage, mwert) { constructor(productId, saxoprintProductId, auflage, mwert) {
this.productId = productId; this.productId = productId;
@ -25,6 +26,27 @@ class Saxoprint {
getProduct() { getProduct() {
$(".loading").show(); $(".loading").show();
var self = this; var self = this;
$.post(
"/apps/plugin/custom/psc/saxoprint/config",
{
saxoprintProductId: this.saxoprintProductId,
productId: self.productId,
config: $("#calc_saxoprint").serialize(),
},
function (data, status) {
self.buildUi(data.config);
if(self.firstLoad && productValues.size > 0) {
self.loadProduct();
}else{
self.buildPrice(data.price);
}
},
);
}
loadProduct() {
$(".loading").removeClass('hidden');
var self = this;
$.post( $.post(
"/apps/plugin/custom/psc/saxoprint/config", "/apps/plugin/custom/psc/saxoprint/config",
{ {
@ -60,8 +82,12 @@ class Saxoprint {
var form = ""; var form = "";
var options = ""; var options = "";
var selected = ""; var selected = "";
var self = this;
$.each(productOptions, function (index, item) { $.each(productOptions, function (index, item) {
if(self.firstLoad && productValues.has('property[' + item.id + ']')) {
item.defaultValue = productValues.get('property[' + item.id + ']');
}
if (item.type == "select") { if (item.type == "select") {
options = ""; options = "";
$.each(item.values, function (i, value) { $.each(item.values, function (i, value) {

View File

@ -8,6 +8,7 @@ class Saxoprint {
this.saxoprintProductId = saxoprintProductId; this.saxoprintProductId = saxoprintProductId;
this.auflage = auflage; this.auflage = auflage;
this.mwert = mwert; this.mwert = mwert;
this.firstLoad = true;
} }
init() { init() {
@ -17,6 +18,28 @@ class Saxoprint {
getProduct() { getProduct() {
$(".loading").toggleClass('hidden'); $(".loading").toggleClass('hidden');
var self = this; var self = this;
$.post(
"/apps/plugin/custom/psc/saxoprint/config",
{
saxoprintProductId: this.saxoprintProductId,
productId: self.productId,
config: $("#calc_saxoprint").serialize(),
},
function (data, status) {
self.buildUi(data.config);
if(self.firstLoad && productValues.size > 0) {
self.loadProduct();
self.firstLoad = false;
}else{
self.buildPrice(data.price);
}
},
);
}
loadProduct() {
$(".loading").removeClass('hidden');
var self = this;
$.post( $.post(
"/apps/plugin/custom/psc/saxoprint/config", "/apps/plugin/custom/psc/saxoprint/config",
{ {
@ -53,7 +76,12 @@ class Saxoprint {
var options = ""; var options = "";
var selected = ""; var selected = "";
var self = this;
console.log(productValues);
$.each(productOptions, function (index, item) { $.each(productOptions, function (index, item) {
if(self.firstLoad && productValues.has('property[' + item.id + ']')) {
item.defaultValue = productValues.get('property[' + item.id + ']');
}
if (item.type == "select") { if (item.type == "select") {
options = ""; options = "";
$.each(item.values, function (i, value) { $.each(item.values, function (i, value) {