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 \
libzip-dev \
mupdf-tools \
imagemagick \
libmcrypt-dev
imagemagick
# Install fileinfo
RUN docker-php-ext-install -j$(nproc) fileinfo
# Install intl
@ -69,9 +67,6 @@ RUN docker-php-ext-install -j$(nproc) intl
# Install mongodb
RUN pecl install mongodb \
&& docker-php-ext-enable mongodb
# Install mcrypt
RUN pecl install mcrypt \
&& docker-php-ext-enable mcrypt
# Install curl
RUN docker-php-ext-install -j$(nproc) curl
# Install Zip
@ -97,8 +92,10 @@ RUN apt-get update && apt-get install -y \
# Install ldap
RUN docker-php-ext-install -j$(nproc) ldap
RUN docker-php-ext-configure imap --with-kerberos --with-imap-ssl && \
docker-php-ext-install -j$(nproc) imap
#RUN docker-php-ext-configure imap --with-kerberos --with-imap-ssl && \
# docker-php-ext-install -j$(nproc) imap
RUN pecl install imap
# 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",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"ky": "^1.8.1",
"lucide-vue-next": "^0.514.0",
"pinia": "^3.0.3",
"reka-ui": "^2.3.1",
@ -420,6 +421,8 @@
"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-darwin-arm64": ["lightningcss-darwin-arm64@1.30.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ=="],

View File

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

View File

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

View File

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

View File

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

View File

@ -1,23 +1,10 @@
<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 { default as DepModel } 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());
}
import Dependency from '../../../model/Dependency.ts'
defineProps<{
dependency: Dependency
}>()
</script>

View File

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

View File

@ -1,8 +1,7 @@
<script lang="ts" setup>
import { ref, watch } from 'vue'
import { useElementStore } from '@/stores/Items'
import { Input } from '@/components/ui/input'
import { Button } from '@/components/ui/button'
import { useElementStore } from '../../../stores/Items'
import { Button } from '../../../components/ui/button'
import { Dependency } from '.'
import { default as DepModel } from '../../../model/Dependency.ts'
import {
@ -12,13 +11,13 @@ import {
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from '@/components/ui/dialog'
} from '../../../components/ui/dialog'
const store = useElementStore()
let openModal = ref(false)
function addDependency(event) {
function addDependency() {
store.getActiveItem.addDependency(new DepModel());
}
@ -44,7 +43,7 @@ watch(openModal, (newOpenModal) => {
</DialogDescription>
</DialogHeader>
<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" />
</div>

View File

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

View File

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

View File

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

View File

@ -1,16 +1,15 @@
<script lang="ts" setup>
import InputElement from '@/model/InputElement';
import InputElement from '../../../model/InputElement';
import { computed } from 'vue';
import { Input } from '@/components/ui/input'
import { SquarePen } from 'lucide-vue-next';
import { Input } from '../../../components/ui/input'
const props = defineProps({
const props = defineProps<{
modelValue: InputElement
})
}>()
let emit = defineEmits(['update:modelValue']);
const theModel = computed({
const theModel = computed<InputElement>({
get: () => props.modelValue,
set: (value) => emit('update:modelValue', value),
});
@ -21,6 +20,6 @@ const theModel = computed({
<template>
<div class="flex gap-2 flex-row items-center">
<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>
</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>
import Row from '@/model/Row';
import Column from '@/model/Column';
import Row from '../../../model/Row';
import Column from '../../../model/Column';
import BaseElement from '../../../model/BaseElement';
import { ref, computed } from 'vue';
import { Input } from '@/components/ui/input'
import { Button } from '@/components/ui/button'
import { SquareDashed } from 'lucide-vue-next';
import EmptyElementForm from './EmptyElementForm.vue'
import { RenderElements } from './../renderelements'
import { useElementStore } from '@/stores/Items'
import Parser from '@/lib/parser'
import { useElementStore } from '../../../stores/Items'
import Parser from '../../../lib/parser'
import { CirclePlus } from 'lucide-vue-next';
const props = defineProps({
interface Props {
modelValue: Row
})
}
const props = defineProps<Props>()
let emit = defineEmits(['update:modelValue']);
const dragUuid = ref("");
@ -29,8 +29,10 @@ const theModel = computed({
const onDrop = (event: DragEvent, targetUuid: string, column: Column) => {
dragUuid.value = ""
if(event.dataTransfer?.getData('mode') == "sort") {
let item = store.cutItem(store.getSourceDragUuid)
let item: BaseElement|null = store.cutItem(store.getSourceDragUuid)
if(item !== null) {
column.items.push(item)
}
store.setDragMode("")
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) => {
dragUuid.value = ""
event.stopImmediatePropagation()

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,28 +1,31 @@
<script lang="ts" setup>
import BaseElement from '@/model/BaseElement';
import BaseElement from '../../../model/BaseElement';
import InputElementForm from '../elements/InputElementForm.vue'
import HiddenElementForm from '../elements/HiddenElementForm.vue'
import HeadlineElementForm from '../elements/HeadlineElementForm.vue'
import TextElementForm from '../elements/TextElementForm.vue'
import MediaElementForm from '../elements/MediaElementForm.vue'
import TextareaElementForm from '../elements/TextareaElementForm.vue'
import SelectElementForm from '../elements/SelectElementForm.vue'
import RowElementForm from '../elements/RowElementForm.vue'
import InputElement from '@/model/InputElement'
import HiddenElement from '@/model/HiddenElement'
import TextElement from '@/model/TextElement'
import TextareaElement from '@/model/TextareaElement'
import HeadlineElement from '@/model/HeadlineElement'
import Row from '@/model/Row'
import SelectElement from '@/model/SelectElement'
import { useElementStore } from '@/stores/Items'
import type { PropType } from 'vue'
import Parser from '@/lib/parser'
import { Settings, Trash, Move, CirclePlus, Waypoints } from 'lucide-vue-next';
import InputElement from '../../../model/InputElement'
import HiddenElement from '../../../model/HiddenElement'
import TextElement from '../../../model/TextElement'
import TextareaElement from '../../../model/TextareaElement'
import HeadlineElement from '../../../model/HeadlineElement'
import MediaElement from '../../../model/MediaElement'
import Row from '../../../model/Row'
import SelectElement from '../../../model/SelectElement'
import { useElementStore } from '../../../stores/Items'
import Parser from '../../../lib/parser'
import { Settings, Trash, CirclePlus, Waypoints } from 'lucide-vue-next';
import { ref } from 'vue'
const props = defineProps({
items: Array as PropType<BaseElement[]>
})
interface Props {
items: BaseElement[]
}
defineProps<Props>()
const store = useElementStore()
@ -111,7 +114,7 @@ const editElementDependency = (item: BaseElement) => {
/>
<HiddenElementForm
v-if="item.type === 1"
v-model="item as InputElement"
v-model="item as HiddenElement"
/>
<SelectElementForm
v-if="item.type === 3"
@ -133,6 +136,10 @@ const editElementDependency = (item: BaseElement) => {
v-if="item.type === 7"
v-model="item as Row"
/>
<MediaElementForm
v-if="item.type === 9"
v-model="item as MediaElement"
/>
</div>
<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">

View File

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

View File

@ -4,7 +4,7 @@ import type { HTMLAttributes } from 'vue'
import { reactiveOmit } from '@vueuse/core'
import { Check } from 'lucide-vue-next'
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 emits = defineEmits<CheckboxRootEmits>()

View File

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

View File

@ -2,7 +2,7 @@
import type { HTMLAttributes } from 'vue'
import { reactiveOmit } from '@vueuse/core'
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'] }>()

View File

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

View File

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

View File

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

View File

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

View File

@ -2,7 +2,7 @@
import type { HTMLAttributes } from 'vue'
import { reactiveOmit } from '@vueuse/core'
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'] }>()

View File

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

View File

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

View File

@ -3,7 +3,7 @@ import type { HTMLAttributes } from 'vue'
import { reactiveOmit } from '@vueuse/core'
import { GripVertical } from 'lucide-vue-next'
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 emits = defineEmits<SplitterResizeHandleEmits>()

View File

@ -2,7 +2,7 @@
import type { HTMLAttributes } from 'vue'
import { reactiveOmit } from '@vueuse/core'
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 emits = defineEmits<SplitterGroupEmits>()

View File

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

View File

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

View File

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

View File

@ -3,7 +3,7 @@ import type { HTMLAttributes } from 'vue'
import { reactiveOmit } from '@vueuse/core'
import { ChevronDown } from 'lucide-vue-next'
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'] }>()

View File

@ -3,7 +3,7 @@ import type { HTMLAttributes } from 'vue'
import { reactiveOmit } from '@vueuse/core'
import { ChevronUp } from 'lucide-vue-next'
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'] }>()

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,7 +1,7 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { useVModel } from '@vueuse/core'
import { cn } from '@/lib/utils'
import { cn } from '../../../lib/utils'
const props = defineProps<{
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 InputElement from "../model/InputElement"
import Row from "../model/Row"
import MediaElement from "../model/MediaElement"
import Column from "../model/Column"
import HiddenElement from "../model/HiddenElement"
import SelectElement from "../model/SelectElement"
@ -12,6 +13,8 @@ export default class Parser {
static getModelForType(type: Number) : BaseElement {
switch(type) {
case 9:
return new MediaElement
case 8:
return new Column
case 7:

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -6,6 +6,17 @@ import vueDevTools from 'vite-plugin-vue-devtools'
export default defineConfig({
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: {
alias: {
'@': 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 ?>';
productLoaded = <?php echo ($this->load) ? 1 : 0 ?>;
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(){
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();
});
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 == "") { ?>
$("#breadcrumbs-Article").attr("href", "/overview/")
<?php } else { ?>
@ -630,6 +651,7 @@ if ($teile[5] == "") {
<?php if (!$this->article->not_buy) : ?>
<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">
<?= $this->formHidden('load', $this->load) ?>
<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="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 ?>';
productLoaded = <?php echo ($this->load) ? 1 : 0 ?>;
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() {
<?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');
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();
@ -14,26 +34,7 @@ $this->headScript()->prependFile('/'. $this->designPath . '/js/saxoprint.js');
</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="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="div-calc" role="tabpanel" aria-labelledby="div-calc-tab">
<div class="md:flex">
@ -63,6 +64,7 @@ $this->headScript()->prependFile('/'. $this->designPath . '/js/saxoprint.js');
<?php if (!$this->article->not_buy) : ?>
<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">
<?= $this->formHidden('load', $this->load) ?>
<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"/>
<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) {
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() {
<?php
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) {
echo 'document.getElementById("upload_mode").value = "' . $this->layouterSession->layouter_modus . '";';
}
if($this->layouterSession) {
echo '$("#upload_mode").val("' . $this->layouterSession->layouter_modus . '");';
}
?>
?>
$('#in_basket').removeClass('disabled');
}
</script>

View File

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

View File

@ -6,6 +6,7 @@ class Saxoprint {
price = 0
options = []
info = []
firstLoad = true
constructor(productId, saxoprintProductId, auflage, mwert) {
this.productId = productId;
@ -25,6 +26,27 @@ class Saxoprint {
getProduct() {
$(".loading").show();
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(
"/apps/plugin/custom/psc/saxoprint/config",
{
@ -60,8 +82,12 @@ class Saxoprint {
var form = "";
var options = "";
var selected = "";
var self = this;
$.each(productOptions, function (index, item) {
if(self.firstLoad && productValues.has('property[' + item.id + ']')) {
item.defaultValue = productValues.get('property[' + item.id + ']');
}
if (item.type == "select") {
options = "";
$.each(item.values, function (i, value) {

View File

@ -8,6 +8,7 @@ class Saxoprint {
this.saxoprintProductId = saxoprintProductId;
this.auflage = auflage;
this.mwert = mwert;
this.firstLoad = true;
}
init() {
@ -17,6 +18,28 @@ class Saxoprint {
getProduct() {
$(".loading").toggleClass('hidden');
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(
"/apps/plugin/custom/psc/saxoprint/config",
{
@ -53,7 +76,12 @@ class Saxoprint {
var options = "";
var selected = "";
var self = this;
console.log(productValues);
$.each(productOptions, function (index, item) {
if(self.firstLoad && productValues.has('property[' + item.id + ']')) {
item.defaultValue = productValues.get('property[' + item.id + ']');
}
if (item.type == "select") {
options = "";
$.each(item.values, function (i, value) {