FormBuilderTS
This commit is contained in:
parent
dd2af7f810
commit
5ac5e328e2
30
src/new/tests/Plugins/System/PSC/XmlCalc/Api/DesignTest.php
Normal file
30
src/new/tests/Plugins/System/PSC/XmlCalc/Api/DesignTest.php
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Plugins\System\PSC\XmlCalc\Api;
|
||||||
|
|
||||||
|
use PSC\Shop\ContactBundle\Repository\ContactRepository;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
||||||
|
use Tests\RefreshDatabaseTrait;
|
||||||
|
|
||||||
|
class DesignTest extends WebTestCase
|
||||||
|
{
|
||||||
|
use RefreshDatabaseTrait;
|
||||||
|
|
||||||
|
public function testDesignApi(): void
|
||||||
|
{
|
||||||
|
$client = static::createClient();
|
||||||
|
|
||||||
|
$client->jsonRequest(
|
||||||
|
'POST',
|
||||||
|
'/api/plugin/system/psc/xmlcalc/product/design',
|
||||||
|
[
|
||||||
|
'product' => '01938686-0e4d-7da9-bae3-b2e1b1681f9f',
|
||||||
|
'jsonProduct' => '[{"uuid":"df2df718-b28e-482d-bf0c-67d246f05d32","name":"Test Artikel","options":[{"id":"auflage","name":"Auflage","default":"100","dependencys":[],"placeHolder":"Placeholder","required":false,"type":2},{"id":"seiten_umschlag","name":"Seiten Umschlag","default":"2","dependencys":[],"placeHolder":"Placeholder","required":false,"type":2},{"id":"seiten_anzahl_inhalt","name":"Seiten Anzahl Inhalt","default":"10","dependencys":[{"relation":"auflage","formula":"","borders":[{"calcValue":"","calcValue1":"","calcValue2":"","calcValue3":"","calcValue4":"","calcValue5":"","calcValue6":"","calcValue7":"","calcValue8":"","calcValue9":"","calcValue10":"","flatRate":"","formula":"$Vauflage$V*0.12","price":0,"value":"1-10","dependencys":[{"relation":"seiten_umschlag","formula":"","borders":[{"calcValue":"","calcValue1":"","calcValue2":"","calcValue3":"","calcValue4":"","calcValue5":"","calcValue6":"","calcValue7":"","calcValue8":"","calcValue9":"","calcValue10":"","flatRate":"","formula":"$Vseiten_umschlag$V*0.24","price":0,"value":"1-2","dependencys":[]},{"calcValue":"","calcValue1":"","calcValue2":"","calcValue3":"","calcValue4":"","calcValue5":"","calcValue6":"","calcValue7":"","calcValue8":"","calcValue9":"","calcValue10":"","flatRate":"","formula":"$Vseiten_umschlag$V*0.23","price":0,"value":"3-","dependencys":[]}]}]},{"calcValue":"","calcValue1":"","calcValue2":"","calcValue3":"","calcValue4":"","calcValue5":"","calcValue6":"","calcValue7":"","calcValue8":"","calcValue9":"","calcValue10":"","flatRate":"","formula":"$Vauflage$V*0.11","price":0,"value":"11-","dependencys":[{"relation":"seiten_umschlag","formula":"","borders":[{"calcValue":"","calcValue1":"","calcValue2":"","calcValue3":"","calcValue4":"","calcValue5":"","calcValue6":"","calcValue7":"","calcValue8":"","calcValue9":"","calcValue10":"","flatRate":"","formula":"$Vseiten_umschlag$V*0.21","price":0,"value":"1-2","dependencys":[]},{"calcValue":"","calcValue1":"","calcValue2":"","calcValue3":"","calcValue4":"","calcValue5":"","calcValue6":"","calcValue7":"","calcValue8":"","calcValue9":"","calcValue10":"","flatRate":"","formula":"$Vseiten_umschlag$V*0.20","price":0,"value":"3-","dependencys":[]}]}]}]}],"placeHolder":"Placeholder","required":true,"type":2},{"id":"farbigkeit","name":"Farbigkeit","default":"10","dependencys":[],"type":3,"options":[{"id":"10","name":"1\/0 farbig","dependencys":[{"relation":"auflage","formula":"","borders":[{"calcValue":"","calcValue1":"","calcValue2":"","calcValue3":"","calcValue4":"","calcValue5":"","calcValue6":"","calcValue7":"","calcValue8":"","calcValue9":"","calcValue10":"","flatRate":"","formula":"","price":0,"value":"1-101","dependencys":[]}]}]},{"id":"11","name":"1\/1 farbig","dependencys":[]},{"id":"20","name":"2\/0 farbig","dependencys":[]},{"id":"21","name":"2\/1 farbig","dependencys":[]},{"id":"22","name":"2\/2 farbig","dependencys":[{"relation":"auflage","formula":"","borders":[{"calcValue":"","calcValue1":"","calcValue2":"","calcValue3":"","calcValue4":"","calcValue5":"","calcValue6":"","calcValue7":"","calcValue8":"","calcValue9":"","calcValue10":"","flatRate":"","formula":"","price":0,"value":"11-50","dependencys":[]}]}]}],"mode":"normal"},{"id":"calc","name":"calc","dependencys":[{"relation":"auflage","formula":"","borders":[{"calcValue":"","calcValue1":"","calcValue2":"","calcValue3":"","calcValue4":"","calcValue5":"","calcValue6":"","calcValue7":"","calcValue8":"","calcValue9":"","calcValue10":"","flatRate":"","formula":"$Vauflage$V*$Vseiten_anzahl_inhalt$V","price":0,"value":"1-","dependencys":[]}]}],"type":1}]}]',
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
$this->assertResponseIsSuccessful();
|
||||||
|
|
||||||
|
self::assertJson($client->getResponse()->getContent());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -21,6 +21,8 @@
|
|||||||
"vue": "^3.5.13",
|
"vue": "^3.5.13",
|
||||||
"vue-codemirror": "^6.1.1",
|
"vue-codemirror": "^6.1.1",
|
||||||
"vue-draggable-plus": "^0.6.0",
|
"vue-draggable-plus": "^0.6.0",
|
||||||
|
"vue-i18n": "^11.1.9",
|
||||||
|
"xml-beautify": "^1.2.3",
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^24.0.1",
|
"@types/node": "^24.0.1",
|
||||||
@ -176,6 +178,12 @@
|
|||||||
|
|
||||||
"@internationalized/number": ["@internationalized/number@3.6.3", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-p+Zh1sb6EfrfVaS86jlHGQ9HA66fJhV9x5LiE5vCbZtXEHAuhcmUZUdZ4WrFpUBfNalr2OkAJI5AcKEQF+Lebw=="],
|
"@internationalized/number": ["@internationalized/number@3.6.3", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-p+Zh1sb6EfrfVaS86jlHGQ9HA66fJhV9x5LiE5vCbZtXEHAuhcmUZUdZ4WrFpUBfNalr2OkAJI5AcKEQF+Lebw=="],
|
||||||
|
|
||||||
|
"@intlify/core-base": ["@intlify/core-base@11.1.9", "", { "dependencies": { "@intlify/message-compiler": "11.1.9", "@intlify/shared": "11.1.9" } }, "sha512-Lrdi4wp3XnGhWmB/mMD/XtfGUw1Jt+PGpZI/M63X1ZqhTDjNHRVCs/i8vv8U1cwaj1A9fb0bkCQHLSL0SK+pIQ=="],
|
||||||
|
|
||||||
|
"@intlify/message-compiler": ["@intlify/message-compiler@11.1.9", "", { "dependencies": { "@intlify/shared": "11.1.9", "source-map-js": "^1.0.2" } }, "sha512-84SNs3Ikjg0rD1bOuchzb3iK1vR2/8nxrkyccIl5DjFTeMzE/Fxv6X+A7RN5ZXjEWelc1p5D4kHA6HEOhlKL5Q=="],
|
||||||
|
|
||||||
|
"@intlify/shared": ["@intlify/shared@11.1.9", "", {}, "sha512-H/83xgU1l8ox+qG305p6ucmoy93qyjIPnvxGWRA7YdOoHe1tIiW9IlEu4lTdsOR7cfP1ecrwyflQSqXdXBacXA=="],
|
||||||
|
|
||||||
"@isaacs/fs-minipass": ["@isaacs/fs-minipass@4.0.1", "", { "dependencies": { "minipass": "^7.0.4" } }, "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w=="],
|
"@isaacs/fs-minipass": ["@isaacs/fs-minipass@4.0.1", "", { "dependencies": { "minipass": "^7.0.4" } }, "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w=="],
|
||||||
|
|
||||||
"@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.8", "", { "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA=="],
|
"@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.8", "", { "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA=="],
|
||||||
@ -610,12 +618,16 @@
|
|||||||
|
|
||||||
"vue-draggable-plus": ["vue-draggable-plus@0.6.0", "", { "dependencies": { "@types/sortablejs": "^1.15.8" } }, "sha512-G5TSfHrt9tX9EjdG49InoFJbt2NYk0h3kgjgKxkFWr3ulIUays0oFObr5KZ8qzD4+QnhtALiRwIqY6qul4egqw=="],
|
"vue-draggable-plus": ["vue-draggable-plus@0.6.0", "", { "dependencies": { "@types/sortablejs": "^1.15.8" } }, "sha512-G5TSfHrt9tX9EjdG49InoFJbt2NYk0h3kgjgKxkFWr3ulIUays0oFObr5KZ8qzD4+QnhtALiRwIqY6qul4egqw=="],
|
||||||
|
|
||||||
|
"vue-i18n": ["vue-i18n@11.1.9", "", { "dependencies": { "@intlify/core-base": "11.1.9", "@intlify/shared": "11.1.9", "@vue/devtools-api": "^6.5.0" }, "peerDependencies": { "vue": "^3.0.0" } }, "sha512-N9ZTsXdRmX38AwS9F6Rh93RtPkvZTkSy/zNv63FTIwZCUbLwwrpqlKz9YQuzFLdlvRdZTnWAUE5jMxr8exdl7g=="],
|
||||||
|
|
||||||
"vue-tsc": ["vue-tsc@2.2.10", "", { "dependencies": { "@volar/typescript": "~2.4.11", "@vue/language-core": "2.2.10" }, "peerDependencies": { "typescript": ">=5.0.0" }, "bin": { "vue-tsc": "./bin/vue-tsc.js" } }, "sha512-jWZ1xSaNbabEV3whpIDMbjVSVawjAyW+x1n3JeGQo7S0uv2n9F/JMgWW90tGWNFRKya4YwKMZgCtr0vRAM7DeQ=="],
|
"vue-tsc": ["vue-tsc@2.2.10", "", { "dependencies": { "@volar/typescript": "~2.4.11", "@vue/language-core": "2.2.10" }, "peerDependencies": { "typescript": ">=5.0.0" }, "bin": { "vue-tsc": "./bin/vue-tsc.js" } }, "sha512-jWZ1xSaNbabEV3whpIDMbjVSVawjAyW+x1n3JeGQo7S0uv2n9F/JMgWW90tGWNFRKya4YwKMZgCtr0vRAM7DeQ=="],
|
||||||
|
|
||||||
"w3c-keyname": ["w3c-keyname@2.2.8", "", {}, "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ=="],
|
"w3c-keyname": ["w3c-keyname@2.2.8", "", {}, "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ=="],
|
||||||
|
|
||||||
"which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
|
"which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
|
||||||
|
|
||||||
|
"xml-beautify": ["xml-beautify@1.2.3", "", {}, "sha512-VsYpkqoVawIP84pi00XukPsgQHqOhgrpwTHlXqqRMAgYZ1u+Yw3KHIUhO1Igf19d5CQ5h6ExJT1hFCJRLmzADg=="],
|
||||||
|
|
||||||
"yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="],
|
"yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="],
|
||||||
|
|
||||||
"yoctocolors": ["yoctocolors@2.1.1", "", {}, "sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ=="],
|
"yoctocolors": ["yoctocolors@2.1.1", "", {}, "sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ=="],
|
||||||
@ -642,6 +654,8 @@
|
|||||||
|
|
||||||
"reka-ui/@vueuse/shared": ["@vueuse/shared@12.8.2", "", { "dependencies": { "vue": "^3.5.13" } }, "sha512-dznP38YzxZoNloI0qpEfpkms8knDtaoQ6Y/sfS0L7Yki4zh40LFHEhur0odJC6xTHG5dxWVPiUWBXn+wCG2s5w=="],
|
"reka-ui/@vueuse/shared": ["@vueuse/shared@12.8.2", "", { "dependencies": { "vue": "^3.5.13" } }, "sha512-dznP38YzxZoNloI0qpEfpkms8knDtaoQ6Y/sfS0L7Yki4zh40LFHEhur0odJC6xTHG5dxWVPiUWBXn+wCG2s5w=="],
|
||||||
|
|
||||||
|
"vue-i18n/@vue/devtools-api": ["@vue/devtools-api@6.6.4", "", {}, "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g=="],
|
||||||
|
|
||||||
"reka-ui/@vueuse/core/@vueuse/metadata": ["@vueuse/metadata@12.8.2", "", {}, "sha512-rAyLGEuoBJ/Il5AmFHiziCPdQzRt88VxR+Y/A/QhJ1EWtWqPBBAxTAFaSkviwEuOEZNtW8pvkPgoCZQ+HxqW1A=="],
|
"reka-ui/@vueuse/core/@vueuse/metadata": ["@vueuse/metadata@12.8.2", "", {}, "sha512-rAyLGEuoBJ/Il5AmFHiziCPdQzRt88VxR+Y/A/QhJ1EWtWqPBBAxTAFaSkviwEuOEZNtW8pvkPgoCZQ+HxqW1A=="],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,7 +26,9 @@
|
|||||||
"uuid": "^11.1.0",
|
"uuid": "^11.1.0",
|
||||||
"vue": "^3.5.13",
|
"vue": "^3.5.13",
|
||||||
"vue-codemirror": "^6.1.1",
|
"vue-codemirror": "^6.1.1",
|
||||||
"vue-draggable-plus": "^0.6.0"
|
"vue-draggable-plus": "^0.6.0",
|
||||||
|
"vue-i18n": "^11.1.9",
|
||||||
|
"xml-beautify": "^1.2.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^24.0.1",
|
"@types/node": "^24.0.1",
|
||||||
|
|||||||
@ -8,7 +8,8 @@ onMounted(() => {
|
|||||||
const params = new URLSearchParams(window.location.search);
|
const params = new URLSearchParams(window.location.search);
|
||||||
const uuid = params.get('uuid');
|
const uuid = params.get('uuid');
|
||||||
if (uuid) {
|
if (uuid) {
|
||||||
store.loadFromApi(uuid);
|
store.loadConfigFromProductApi(uuid);
|
||||||
|
store.loadFormulaAnalyserDataFromApi(uuid);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -7,8 +7,7 @@ import {
|
|||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '../components/ui/tabs'
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from '../components/ui/tabs'
|
||||||
|
|
||||||
import { Library } from '../components/app/library'
|
import { Library } from '../components/app/library'
|
||||||
import { Debug } from '../components/app/debug'
|
import { ElementProperties, SpecialElementProperties } 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'
|
||||||
import FormulaVisualizer from './app/FormulaVisualizer.vue'
|
import FormulaVisualizer from './app/FormulaVisualizer.vue'
|
||||||
@ -26,7 +25,6 @@ import XmlView from './app/XmlView.vue'
|
|||||||
<ResizablePanel id="" :default-size="15">
|
<ResizablePanel id="" :default-size="15">
|
||||||
<div class="flex flex-col gap-2 h-full">
|
<div class="flex flex-col gap-2 h-full">
|
||||||
<Library />
|
<Library />
|
||||||
<Debug />
|
|
||||||
</div>
|
</div>
|
||||||
</ResizablePanel>
|
</ResizablePanel>
|
||||||
<ResizableHandle id="" with-handle />
|
<ResizableHandle id="" with-handle />
|
||||||
@ -35,16 +33,16 @@ import XmlView from './app/XmlView.vue'
|
|||||||
<div class="flex justify-center">
|
<div class="flex justify-center">
|
||||||
<TabsList>
|
<TabsList>
|
||||||
<TabsTrigger value="designer">
|
<TabsTrigger value="designer">
|
||||||
Designer
|
{{ $t('designer') }}
|
||||||
</TabsTrigger>
|
</TabsTrigger>
|
||||||
<TabsTrigger value="preview">
|
<TabsTrigger value="preview">
|
||||||
Kalkulations Analyse
|
{{ $t('preview') }}
|
||||||
</TabsTrigger>
|
</TabsTrigger>
|
||||||
<TabsTrigger value="xml">
|
<TabsTrigger value="xml">
|
||||||
XML Ansicht
|
{{ $t('xml_view') }}
|
||||||
</TabsTrigger>
|
</TabsTrigger>
|
||||||
<TabsTrigger value="json">
|
<TabsTrigger value="json">
|
||||||
JSON Ansicht
|
{{ $t('json_view') }}
|
||||||
</TabsTrigger>
|
</TabsTrigger>
|
||||||
</TabsList>
|
</TabsList>
|
||||||
</div>
|
</div>
|
||||||
@ -66,6 +64,7 @@ import XmlView from './app/XmlView.vue'
|
|||||||
</ResizablePanel>
|
</ResizablePanel>
|
||||||
</ResizablePanelGroup>
|
</ResizablePanelGroup>
|
||||||
<ElementProperties />
|
<ElementProperties />
|
||||||
|
<SpecialElementProperties />
|
||||||
<ElementDependency />
|
<ElementDependency />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -1,22 +1,8 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted, provide } from 'vue';
|
import { ref, onMounted, provide, computed } from 'vue';
|
||||||
import NodeRenderer from './NodeRenderer.vue';
|
import NodeRenderer from './NodeRenderer.vue';
|
||||||
import { loadPriceFromApi } from '../../lib/api';
|
|
||||||
import { useElementStore } from '../../stores/Items';
|
import { useElementStore } from '../../stores/Items';
|
||||||
|
|
||||||
// Debounce function to limit the rate at which a function gets called.
|
|
||||||
function debounce<T extends (...args: any[]) => any>(func: T, delay: number): (...args: Parameters<T>) => void {
|
|
||||||
let timeoutId: ReturnType<typeof setTimeout> | null = null;
|
|
||||||
return (...args: Parameters<T>) => {
|
|
||||||
if (timeoutId) {
|
|
||||||
clearTimeout(timeoutId);
|
|
||||||
}
|
|
||||||
timeoutId = setTimeout(() => {
|
|
||||||
func(...args);
|
|
||||||
}, delay);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Node {
|
interface Node {
|
||||||
name: string;
|
name: string;
|
||||||
unParsed?: string;
|
unParsed?: string;
|
||||||
@ -25,50 +11,12 @@ interface Node {
|
|||||||
parts: Node[];
|
parts: Node[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const parsedData = ref<Node[] | null>(null);
|
|
||||||
const expandedNodes = ref(new Set<string>());
|
const expandedNodes = ref(new Set<string>());
|
||||||
const error = ref('');
|
|
||||||
const isLoading = ref(false);
|
|
||||||
const store = useElementStore();
|
const store = useElementStore();
|
||||||
|
|
||||||
const loadFormulaData = async () => {
|
const parsedData = computed(() => store.getFormulaData);
|
||||||
isLoading.value = true;
|
const error = computed(() => store.getFormulaError);
|
||||||
error.value = '';
|
const isLoading = computed(() => store.isFormulaLoading);
|
||||||
parsedData.value = null;
|
|
||||||
|
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
|
||||||
const uuid = urlParams.get('uuid');
|
|
||||||
|
|
||||||
if (!uuid) {
|
|
||||||
error.value = 'Keine UUID in der URL gefunden.';
|
|
||||||
isLoading.value = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await loadPriceFromApi(uuid);
|
|
||||||
if (response && response.debug && response.debug.graphJson) {
|
|
||||||
const graphData = JSON.parse(response.debug.graphJson);
|
|
||||||
parsedData.value = graphData;
|
|
||||||
} else {
|
|
||||||
throw new Error('Ungültiges oder leeres Antwortformat von der API.');
|
|
||||||
}
|
|
||||||
} catch (e: any) {
|
|
||||||
error.value = `Fehler beim Laden der Formeldaten: ${e.message}`;
|
|
||||||
console.error(e);
|
|
||||||
} finally {
|
|
||||||
isLoading.value = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const debouncedLoadFormulaData = debounce(loadFormulaData, 500);
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
loadFormulaData();
|
|
||||||
store.$subscribe(() => {
|
|
||||||
debouncedLoadFormulaData();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
const toggleNode = (nodeId: string) => {
|
const toggleNode = (nodeId: string) => {
|
||||||
const newExpanded = new Set(expandedNodes.value);
|
const newExpanded = new Set(expandedNodes.value);
|
||||||
|
|||||||
@ -10,11 +10,19 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue';
|
import { computed } from 'vue';
|
||||||
import { Codemirror } from 'vue-codemirror';
|
import { Codemirror } from 'vue-codemirror';
|
||||||
import { xml } from '@codemirror/lang-xml';
|
import { xml } from '@codemirror/lang-xml';
|
||||||
|
import { useElementStore } from '../../stores/Items';
|
||||||
|
import XmlBeautify from 'xml-beautify'
|
||||||
|
|
||||||
const xmlString = ref('<root>\n <!-- XML Data Source Not Yet Implemented -->\n</root>');
|
const store = useElementStore();
|
||||||
|
|
||||||
|
const xmlString = computed(() => new XmlBeautify().beautify(store.xml,
|
||||||
|
{
|
||||||
|
indent: " ", //indent pattern like white spaces
|
||||||
|
useSelfClosingElement: true //true:use self-closing element when empty element.
|
||||||
|
}));
|
||||||
|
|
||||||
const extensions = [xml()];
|
const extensions = [xml()];
|
||||||
|
|
||||||
|
|||||||
@ -1,24 +0,0 @@
|
|||||||
<script lang="ts" setup>
|
|
||||||
import { useElementStore } from '../../../stores/Items';
|
|
||||||
import { Textarea } from '../../../components/ui/textarea'
|
|
||||||
import { Button } from '../../../components/ui/button'
|
|
||||||
const store = useElementStore()
|
|
||||||
|
|
||||||
function loadJson() {
|
|
||||||
store.loadJSON()
|
|
||||||
}
|
|
||||||
|
|
||||||
function restoreJson() {
|
|
||||||
store.parseJSON()
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div class="p-1">
|
|
||||||
<Textarea v-model="store.json" class="h-50"/>
|
|
||||||
<div class="flex flex-row mt-2 gap-1">
|
|
||||||
<Button class="grow" v-on:click="loadJson()">Load Json</Button>
|
|
||||||
<Button class="grow" v-on:click="restoreJson()">Restore Json</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
@ -1 +0,0 @@
|
|||||||
export { default as Debug } from './Debug.vue'
|
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { useElementStore } from '../../../stores/Items'
|
||||||
|
import SelectSpecialProperties from '../properties/SelectSpecial.vue'
|
||||||
|
import { ref, watch } from 'vue'
|
||||||
|
|
||||||
|
|
||||||
|
let emit = defineEmits(['update:modelValue']);
|
||||||
|
const store = useElementStore()
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="">
|
||||||
|
<SelectSpecialProperties
|
||||||
|
v-model="store.getActiveItem as SelectElement"
|
||||||
|
>
|
||||||
|
</SelectSpecialProperties>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@ -1 +1,2 @@
|
|||||||
export { default as ElementProperties } from './ElementProperties.vue'
|
export { default as ElementProperties } from './ElementProperties.vue'
|
||||||
|
export { default as SpecialElementProperties } from './SpecialProperties.vue'
|
||||||
|
|||||||
@ -19,7 +19,7 @@ const theModel = computed<InputElement>({
|
|||||||
|
|
||||||
<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}}</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>
|
||||||
|
|||||||
@ -4,7 +4,9 @@ import { Image, SquareParking, SquareDot, SquareMenu, SquarePen, SquareChevronDo
|
|||||||
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'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
|
const { t, locale } = useI18n()
|
||||||
const store = useElementStore()
|
const store = useElementStore()
|
||||||
|
|
||||||
let previewMode = ref(false)
|
let previewMode = ref(false)
|
||||||
@ -30,41 +32,47 @@ watch(previewMode, (newPreviewMode) => {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col p-3 gap-3 overflow-auto">
|
<div class="flex flex-col p-3 gap-3 overflow-auto">
|
||||||
|
<div class="flex items-center space-x-2">
|
||||||
|
<select v-model="locale">
|
||||||
|
<option value="de">DE</option>
|
||||||
|
<option value="en">EN</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
<div class="flex items-center space-x-2">
|
<div class="flex items-center space-x-2">
|
||||||
<Switch id="preview-mode" v-model="previewMode" />
|
<Switch id="preview-mode" v-model="previewMode" />
|
||||||
<Label for="preview-mode">Preview Mode</Label>
|
<Label for="preview-mode">{{ $t('preview_mode') }}</Label>
|
||||||
</div>
|
</div>
|
||||||
<div id="headline" class="border-1 p-2 w-full flex flex-row gap-2" draggable="true" @dragstart="startDrag($event, '6')" @dragenter.prevent @dragover.prevent>
|
<div id="headline" class="border-1 p-2 w-full flex flex-row gap-2" draggable="true" @dragstart="startDrag($event, '6')" @dragenter.prevent @dragover.prevent>
|
||||||
<SquareDot />
|
<SquareDot />
|
||||||
<span>Headline</span>
|
<span>{{ $t('headline') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div id="text" class="border-1 p-2 w-full flex flex-row gap-2" draggable="true" @dragstart="startDrag($event, '4')" @dragenter.prevent @dragover.prevent>
|
<div id="text" class="border-1 p-2 w-full flex flex-row gap-2" draggable="true" @dragstart="startDrag($event, '4')" @dragenter.prevent @dragover.prevent>
|
||||||
<SquareParking />
|
<SquareParking />
|
||||||
<span>Text</span>
|
<span>{{ $t('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>
|
<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 />
|
<Image />
|
||||||
<span>Media</span>
|
<span>{{ $t('media') }}</span>
|
||||||
</div>
|
</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>{{ $t('textarea') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div id="input" class="border-1 p-2 w-full flex flex-row gap-2" draggable="true" @dragstart="startDrag($event, '2')" @dragenter.prevent @dragover.prevent>
|
<div id="input" class="border-1 p-2 w-full flex flex-row gap-2" draggable="true" @dragstart="startDrag($event, '2')" @dragenter.prevent @dragover.prevent>
|
||||||
<SquarePen />
|
<SquarePen />
|
||||||
<span>Input</span>
|
<span>{{ $t('input') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div id="select" class="border-1 p-2 w-full flex flex-row gap-2" draggable="true" @dragstart="startDrag($event, '3')" @dragenter.prevent @dragover.prevent>
|
<div id="select" class="border-1 p-2 w-full flex flex-row gap-2" draggable="true" @dragstart="startDrag($event, '3')" @dragenter.prevent @dragover.prevent>
|
||||||
<SquareChevronDown />
|
<SquareChevronDown />
|
||||||
<span>Select</span>
|
<span>{{ $t('select') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div id="hidden" class="border-1 p-2 w-full flex flex-row gap-2" draggable="true" @dragstart="startDrag($event, '1')" @dragenter.prevent @dragover.prevent>
|
<div id="hidden" class="border-1 p-2 w-full flex flex-row gap-2" draggable="true" @dragstart="startDrag($event, '1')" @dragenter.prevent @dragover.prevent>
|
||||||
<SquareDashed />
|
<SquareDashed />
|
||||||
<span>Hidden</span>
|
<span>{{ $t('hidden') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div id="row" class="border-1 p-2 w-full flex flex-row gap-2" draggable="true" @dragstart="startDrag($event, '7')" @dragenter.prevent @dragover.prevent>
|
<div id="row" class="border-1 p-2 w-full flex flex-row gap-2" draggable="true" @dragstart="startDrag($event, '7')" @dragenter.prevent @dragover.prevent>
|
||||||
<SquareDashed />
|
<SquareDashed />
|
||||||
<span>Row</span>
|
<span>{{ $t('row') }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -25,13 +25,13 @@ const theModel = computed({
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<label>ID</label>
|
<label>{{ $t('id') }}</label>
|
||||||
<Input v-model="theModel!.id" />
|
<Input v-model="theModel!.id" />
|
||||||
<label>Default</label>
|
<label>{{ $t('default') }}</label>
|
||||||
<Input v-model="theModel!.default"/>
|
<Input v-model="theModel!.default"/>
|
||||||
<label>Name</label>
|
<label>{{ $t('name') }}</label>
|
||||||
<Input v-model="theModel!.name"/>
|
<Input v-model="theModel!.name"/>
|
||||||
<label>Variant</label>
|
<label>{{ $t('variant') }}</label>
|
||||||
<Select v-model="theModel!.variant">
|
<Select v-model="theModel!.variant">
|
||||||
<SelectTrigger>
|
<SelectTrigger>
|
||||||
<SelectValue />
|
<SelectValue />
|
||||||
@ -39,22 +39,22 @@ const theModel = computed({
|
|||||||
<SelectContent>
|
<SelectContent>
|
||||||
<SelectGroup>
|
<SelectGroup>
|
||||||
<SelectItem value="1">
|
<SelectItem value="1">
|
||||||
Headline 1
|
{{ $t('headline1') }}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
<SelectItem value="2">
|
<SelectItem value="2">
|
||||||
Headline 2
|
{{ $t('headline2') }}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
<SelectItem value="3">
|
<SelectItem value="3">
|
||||||
Headline 3
|
{{ $t('headline3') }}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
<SelectItem value="4">
|
<SelectItem value="4">
|
||||||
Headline 4
|
{{ $t('headline4') }}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
<SelectItem value="5">
|
<SelectItem value="5">
|
||||||
Headline 5
|
{{ $t('headline5') }}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
<SelectItem value="6">
|
<SelectItem value="6">
|
||||||
Headline 6
|
{{ $t('headline6') }}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
</SelectGroup>
|
</SelectGroup>
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
|
|||||||
@ -17,10 +17,10 @@ const theModel = computed({
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<label>ID</label>
|
<label>{{ $t('id') }}</label>
|
||||||
<Input v-model="theModel!.id" />
|
<Input v-model="theModel!.id" />
|
||||||
<label>Default</label>
|
<label>{{ $t('default') }}</label>
|
||||||
<Input v-model="theModel!.default"/>
|
<Input v-model="theModel!.default"/>
|
||||||
<label>Name</label>
|
<label>{{ $t('name') }}</label>
|
||||||
<Input v-model="theModel!.name"/>
|
<Input v-model="theModel!.name"/>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -18,18 +18,22 @@ const theModel = computed<InputElement>({
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<label>ID</label>
|
<label>{{ $t('id') }}</label>
|
||||||
<Input v-model="theModel!.id" />
|
<Input v-model="theModel!.id" />
|
||||||
<label>Placeholder</label>
|
<label>{{ $t('placeholder') }}</label>
|
||||||
<Input v-model="theModel!.placeHolder"/>
|
<Input v-model="theModel!.placeHolder"/>
|
||||||
<label>Default</label>
|
<label>{{ $t('default') }}</label>
|
||||||
<Input v-model="theModel!.default"/>
|
<Input v-model="theModel!.default"/>
|
||||||
<label>Name</label>
|
<label>{{ $t('name') }}</label>
|
||||||
<Input v-model="theModel!.name"/>
|
<Input v-model="theModel!.name"/>
|
||||||
<Checkbox v-model="theModel!.required"/>
|
<Checkbox v-model="theModel!.required"/>
|
||||||
<label class="form-check-label" for="flexSwitchCheckDefault">Required</label>
|
<label class="form-check-label" for="flexSwitchCheckDefault">{{ $t('required') }}</label>
|
||||||
<label>Min</label>
|
<label>{{ $t('min') }}</label>
|
||||||
<Input v-model="theModel!.minValue"/>
|
<Input v-model="theModel!.minValue"/>
|
||||||
<label>Max</label>
|
<label>{{ $t('max') }}</label>
|
||||||
<Input v-model="theModel!.maxValue"/>
|
<Input v-model="theModel!.maxValue"/>
|
||||||
|
<label>{{ $t('min_calc') }}</label>
|
||||||
|
<Input v-model="theModel!.minCalc"/>
|
||||||
|
<label>{{ $t('max_calc') }}</label>
|
||||||
|
<Input v-model="theModel!.maxCalc"/>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -20,10 +20,10 @@ const theModel = computed({
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<label>ID</label>
|
<label>{{ $t('id') }}</label>
|
||||||
<Input v-model="theModel!.id" />
|
<Input v-model="theModel!.id" />
|
||||||
<label>Default</label>
|
<label>{{ $t('default') }}</label>
|
||||||
<Input v-model="theModel!.default"/>
|
<Input v-model="theModel!.default"/>
|
||||||
<label>Name</label>
|
<label>{{ $t('name') }}</label>
|
||||||
<Input v-model="theModel!.name"/>
|
<Input v-model="theModel!.name"/>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -26,11 +26,11 @@ const theModel = computed<Option>({
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="flex flex-row gap-1">
|
<div class="flex flex-row gap-1">
|
||||||
<label>ID</label>
|
<label>{{ $t('id') }}</label>
|
||||||
<Input v-model="theModel.id" />
|
<Input v-model="theModel.id" />
|
||||||
<label>Name</label>
|
<label>{{ $t('name') }}</label>
|
||||||
<Input v-model="theModel.name"/>
|
<Input v-model="theModel.name"/>
|
||||||
<Button v-on:click="addDependency(theModel)">Add Dependency</Button>
|
<Button v-on:click="addDependency(theModel)">{{ $t('add_dependency') }}</Button>
|
||||||
</div>
|
</div>
|
||||||
<Dependency :dependencys="theModel.dependencys" />
|
<Dependency :dependencys="theModel.dependencys" />
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -24,5 +24,5 @@ function addColumn(row: Row) {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Button v-on:click="addColumn(theModel!)">add Column</Button>
|
<Button v-on:click="addColumn(theModel!)">{{ $t('add_column') }}</Button>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -23,31 +23,29 @@ import {
|
|||||||
DialogTitle,
|
DialogTitle,
|
||||||
DialogTrigger,
|
DialogTrigger,
|
||||||
} from '../../../components/ui/dialog'
|
} from '../../../components/ui/dialog'
|
||||||
|
import { ref, watch } from 'vue'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
modelValue: SelectElement
|
modelValue: SelectElement
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
let emit = defineEmits(['update:modelValue']);
|
let emit = defineEmits(['update:modelValue'])
|
||||||
|
|
||||||
const theModel = computed<SelectElement>({
|
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: SelectElement) {
|
|
||||||
obj.addOption(new Option(String(obj.options.length + 1)));
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<label>ID</label>
|
<label>{{ $t('id') }}</label>
|
||||||
<Input v-model="theModel!.id" />
|
<Input v-model="theModel!.id" />
|
||||||
<label>Default</label>
|
<label>{{ $t('default') }}</label>
|
||||||
<Input v-model="theModel!.default"/>
|
<Input v-model="theModel!.default"/>
|
||||||
<label>Name</label>
|
<label>{{ $t('name') }}</label>
|
||||||
<Input v-model="theModel!.name"/>
|
<Input v-model="theModel!.name"/>
|
||||||
<label>Mode</label>
|
<label>{{ $t('mode') }}</label>
|
||||||
<Select v-model="theModel!.mode">
|
<Select v-model="theModel!.mode">
|
||||||
<SelectTrigger>
|
<SelectTrigger>
|
||||||
<SelectValue />
|
<SelectValue />
|
||||||
@ -55,42 +53,17 @@ function addOption(obj: SelectElement) {
|
|||||||
<SelectContent>
|
<SelectContent>
|
||||||
<SelectGroup>
|
<SelectGroup>
|
||||||
<SelectItem value="normal">
|
<SelectItem value="normal">
|
||||||
Normal
|
{{ $t('normal') }}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
<SelectItem value="paperdb">
|
<SelectItem value="paperdb">
|
||||||
PaperDB
|
{{ $t('paperdb') }}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
<SelectItem value="colordb">
|
<SelectItem value="colordb">
|
||||||
ColorDB
|
{{ $t('colordb') }}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
</SelectGroup>
|
</SelectGroup>
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
<label>Container</label>
|
<label>{{ $t('container') }}</label>
|
||||||
<Input v-model="theModel!.container"/>
|
<Input v-model="theModel!.container"/>
|
||||||
<Dialog >
|
|
||||||
<DialogTrigger>
|
|
||||||
<Button class="mt-2">Edit Options</Button>
|
|
||||||
</DialogTrigger>
|
|
||||||
<DialogContent class="min-w-full grid-rows-[auto_minmax(0,1fr)_auto] p-4 max-h-[90dvh]">
|
|
||||||
<DialogHeader>
|
|
||||||
<DialogTitle>Edit Options</DialogTitle>
|
|
||||||
<DialogDescription>
|
|
||||||
<Button v-on:click="addOption(theModel)">Add Option</Button>
|
|
||||||
</DialogDescription>
|
|
||||||
</DialogHeader>
|
|
||||||
<div class="w-full grid overflow-y-auto px-6">
|
|
||||||
<div class="d-flex flex-wrap p-2 relative" v-for="opt in theModel.options" :key="opt.uuid">
|
|
||||||
<OptionElement :option="opt"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<DialogFooter>
|
|
||||||
<DialogClose as-child>
|
|
||||||
<Button type="button" variant="secondary">
|
|
||||||
Close
|
|
||||||
</Button>
|
|
||||||
</DialogClose>
|
|
||||||
</DialogFooter>
|
|
||||||
</DialogContent>
|
|
||||||
</Dialog>
|
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -0,0 +1,87 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { useElementStore } from '../../../stores/Items'
|
||||||
|
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 {
|
||||||
|
Select,
|
||||||
|
SelectContent,
|
||||||
|
SelectGroup,
|
||||||
|
SelectItem,
|
||||||
|
SelectTrigger,
|
||||||
|
SelectValue,
|
||||||
|
} from '../../../components/ui/select'
|
||||||
|
import OptionElement from './OptionElement.vue'
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogClose,
|
||||||
|
DialogDescription,
|
||||||
|
DialogFooter,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
DialogTrigger,
|
||||||
|
} from '../../../components/ui/dialog'
|
||||||
|
import { ref, watch } from 'vue'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
modelValue: SelectElement
|
||||||
|
}>()
|
||||||
|
|
||||||
|
let emit = defineEmits(['update:modelValue'])
|
||||||
|
|
||||||
|
let openModal = ref(false)
|
||||||
|
|
||||||
|
const theModel = computed<SelectElement>({
|
||||||
|
get: () => props.modelValue,
|
||||||
|
set: (value) => emit('update:modelValue', value),
|
||||||
|
});
|
||||||
|
|
||||||
|
function addOption(obj: SelectElement) {
|
||||||
|
obj.addOption(new Option(String(obj.options.length + 1)));
|
||||||
|
}
|
||||||
|
const store = useElementStore()
|
||||||
|
|
||||||
|
store.$subscribe((mutation, state) => {
|
||||||
|
if(state.showOptions) {
|
||||||
|
openModal.value = true
|
||||||
|
}
|
||||||
|
}, true)
|
||||||
|
|
||||||
|
watch(openModal, (newOpenModal) => {
|
||||||
|
if(newOpenModal === false) {
|
||||||
|
store.setShowOptions(false)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Dialog v-if="store.getActiveItem.type === 3" v-model:open="openModal">
|
||||||
|
<DialogTrigger>
|
||||||
|
<Button class="mt-2">{{ $t('edit_options') }}</Button>
|
||||||
|
</DialogTrigger>
|
||||||
|
<DialogContent class="min-w-full grid-rows-[auto_minmax(0,1fr)_auto] p-4 max-h-[90dvh]">
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle>{{ $t('edit_options') }}</DialogTitle>
|
||||||
|
<DialogDescription>
|
||||||
|
<Button v-on:click="addOption(theModel)">{{ $t('add_option') }}</Button>
|
||||||
|
</DialogDescription>
|
||||||
|
</DialogHeader>
|
||||||
|
<div class="w-full grid overflow-y-auto px-6">
|
||||||
|
<div class="d-flex flex-wrap p-2 relative" v-for="opt in theModel.options" :key="opt.uuid">
|
||||||
|
<OptionElement :option="opt"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<DialogFooter>
|
||||||
|
<DialogClose as-child>
|
||||||
|
<Button type="button" variant="secondary">
|
||||||
|
{{ $t('close') }}
|
||||||
|
</Button>
|
||||||
|
</DialogClose>
|
||||||
|
</DialogFooter>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
@ -18,10 +18,10 @@ const theModel = computed<TextElement>({
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<label>ID</label>
|
<label>{{ $t('id') }}</label>
|
||||||
<Input v-model="theModel!.id" />
|
<Input v-model="theModel!.id" />
|
||||||
<label>Name</label>
|
<label>{{ $t('name') }}</label>
|
||||||
<Input v-model="theModel!.name"/>
|
<Input v-model="theModel!.name"/>
|
||||||
<label>Default</label>
|
<label>{{ $t('default') }}</label>
|
||||||
<Textarea v-model="theModel!.default"/>
|
<Textarea v-model="theModel!.default"/>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -19,10 +19,10 @@ const theModel = computed<TextareaElement>({
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<label>ID</label>
|
<label>{{ $t('id') }}</label>
|
||||||
<Input v-model="theModel.id" />
|
<Input v-model="theModel.id" />
|
||||||
<label>Name</label>
|
<label>{{ $t('name') }}</label>
|
||||||
<Input v-model="theModel.name"/>
|
<Input v-model="theModel.name"/>
|
||||||
<label>Default</label>
|
<label>{{ $t('default') }}</label>
|
||||||
<Textarea v-model="theModel.default"/>
|
<Textarea v-model="theModel.default"/>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -18,7 +18,7 @@ import Row from '../../../model/Row'
|
|||||||
import SelectElement from '../../../model/SelectElement'
|
import SelectElement from '../../../model/SelectElement'
|
||||||
import { useElementStore } from '../../../stores/Items'
|
import { useElementStore } from '../../../stores/Items'
|
||||||
import Parser from '../../../lib/parser'
|
import Parser from '../../../lib/parser'
|
||||||
import { Settings, Trash, CirclePlus, Waypoints } from 'lucide-vue-next';
|
import { Settings, Trash, CirclePlus, List, Option } from 'lucide-vue-next';
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@ -86,12 +86,16 @@ const deleteItem = (item: BaseElement) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const editElementProperties = (item: BaseElement) => {
|
const editElementProperties = (item: BaseElement) => {
|
||||||
store.setShowProperties(true)
|
|
||||||
store.setActiveItem(item)
|
store.setActiveItem(item)
|
||||||
|
store.setShowProperties(true)
|
||||||
|
}
|
||||||
|
const editOptions = (item: BaseElement) => {
|
||||||
|
store.setActiveItem(item)
|
||||||
|
store.setShowOptions(true)
|
||||||
}
|
}
|
||||||
const editElementDependency = (item: BaseElement) => {
|
const editElementDependency = (item: BaseElement) => {
|
||||||
store.setShowDependency(true)
|
|
||||||
store.setActiveItem(item)
|
store.setActiveItem(item)
|
||||||
|
store.setShowDependency(true)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -106,7 +110,7 @@ const editElementDependency = (item: BaseElement) => {
|
|||||||
<span class="absolute px-3 font-medium text-gray-900 -translate-x-1/2 bg-white left-1/2 dark:text-white dark:bg-gray-900 pointer-events-none"><CirclePlus :class="{ 'text-orange-500': dragUuid == item.uuid }" class="transition duration-200 pointer-events-none" /></span>
|
<span class="absolute px-3 font-medium text-gray-900 -translate-x-1/2 bg-white left-1/2 dark:text-white dark:bg-gray-900 pointer-events-none"><CirclePlus :class="{ 'text-orange-500': dragUuid == item.uuid }" class="transition duration-200 pointer-events-none" /></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div :class="{ 'border-white' : item.dependencys.length == 0, 'border-blue-500': item.dependencys.length > 0 }" @dragstart="startDrag($event, item.uuid)" draggable="true" class="element w-full flex flex-row border-l-2 hover:border-orange-500 pl-2 transition duration-500 min-h-5" v-bind:class="{ ' bg-slate-50': item.isFocused === true }">
|
<div :class="{ 'border-white' : !item.hasDependencys(), 'border-blue-500': item.hasDependencys() }" @dragstart="startDrag($event, item.uuid)" draggable="true" class="element w-full flex flex-row border-l-2 hover:border-orange-500 pl-2 transition duration-500 min-h-5" v-bind:class="{ ' bg-slate-50': item.isFocused === true }">
|
||||||
<div class="grow content-center items-center">
|
<div class="grow content-center items-center">
|
||||||
<InputElementForm
|
<InputElementForm
|
||||||
v-if="item.type === 2"
|
v-if="item.type === 2"
|
||||||
@ -142,10 +146,13 @@ const editElementDependency = (item: BaseElement) => {
|
|||||||
/>
|
/>
|
||||||
</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)" :title="$t('dependencies')" class="m-2 cursor-pointer">
|
||||||
<Waypoints />
|
<Option />
|
||||||
</div>
|
</div>
|
||||||
<div v-on:click="editElementProperties(item)" class="m-2 cursor-pointer">
|
<div v-if="item.type === 3" v-on:click="editOptions(item)" :title="$t('options')" class="m-2 cursor-pointer">
|
||||||
|
<List />
|
||||||
|
</div>
|
||||||
|
<div v-on:click="editElementProperties(item)" :title="$t('settings')" class="m-2 cursor-pointer">
|
||||||
<Settings />
|
<Settings />
|
||||||
</div>
|
</div>
|
||||||
<div v-on:click="deleteItem(item)" class="text-red-500 m-2 cursor-pointer">
|
<div v-on:click="deleteItem(item)" class="text-red-500 m-2 cursor-pointer">
|
||||||
|
|||||||
@ -0,0 +1,44 @@
|
|||||||
|
{
|
||||||
|
"designer": "Designer",
|
||||||
|
"preview": "Kalkulations Analyse",
|
||||||
|
"xml_view": "XML Ansicht",
|
||||||
|
"json_view": "JSON Ansicht",
|
||||||
|
"preview_mode": "Vorschau-Modus",
|
||||||
|
"headline": "Überschrift",
|
||||||
|
"text": "Text",
|
||||||
|
"media": "Medien",
|
||||||
|
"textarea": "Textbereich",
|
||||||
|
"input": "Eingabefeld",
|
||||||
|
"select": "Auswahl",
|
||||||
|
"hidden": "Versteckt",
|
||||||
|
"row": "Zeile",
|
||||||
|
"id": "ID",
|
||||||
|
"default": "Standard",
|
||||||
|
"name": "Name",
|
||||||
|
"variant": "Variante",
|
||||||
|
"headline1": "Überschrift 1",
|
||||||
|
"headline2": "Überschrift 2",
|
||||||
|
"headline3": "Überschrift 3",
|
||||||
|
"headline4": "Überschrift 4",
|
||||||
|
"headline5": "Überschrift 5",
|
||||||
|
"headline6": "Überschrift 6",
|
||||||
|
"placeholder": "Platzhalter",
|
||||||
|
"required": "Erforderlich",
|
||||||
|
"min": "Min",
|
||||||
|
"max": "Max",
|
||||||
|
"min_calc": "Min Calc",
|
||||||
|
"max_calc": "Max Calc",
|
||||||
|
"add_dependency": "Abhängigkeit hinzufügen",
|
||||||
|
"add_column": "Spalte hinzufügen",
|
||||||
|
"mode": "Modus",
|
||||||
|
"normal": "Normal",
|
||||||
|
"paperdb": "PapierDB",
|
||||||
|
"colordb": "FarbDB",
|
||||||
|
"container": "Container",
|
||||||
|
"edit_options": "Optionen bearbeiten",
|
||||||
|
"add_option": "Option hinzufügen",
|
||||||
|
"close": "Schließen",
|
||||||
|
"dependencies": "Abhängigkeiten",
|
||||||
|
"options": "Optionen",
|
||||||
|
"settings": "Einstellungen"
|
||||||
|
}
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
{
|
||||||
|
"designer": "Designer",
|
||||||
|
"preview": "Calculation Analysis",
|
||||||
|
"xml_view": "XML View",
|
||||||
|
"json_view": "JSON View",
|
||||||
|
"preview_mode": "Preview Mode",
|
||||||
|
"headline": "Headline",
|
||||||
|
"text": "Text",
|
||||||
|
"media": "Media",
|
||||||
|
"textarea": "Textarea",
|
||||||
|
"input": "Input",
|
||||||
|
"select": "Select",
|
||||||
|
"hidden": "Hidden",
|
||||||
|
"row": "Row",
|
||||||
|
"id": "ID",
|
||||||
|
"default": "Default",
|
||||||
|
"name": "Name",
|
||||||
|
"variant": "Variant",
|
||||||
|
"headline1": "Headline 1",
|
||||||
|
"headline2": "Headline 2",
|
||||||
|
"headline3": "Headline 3",
|
||||||
|
"headline4": "Headline 4",
|
||||||
|
"headline5": "Headline 5",
|
||||||
|
"headline6": "Headline 6",
|
||||||
|
"placeholder": "Placeholder",
|
||||||
|
"required": "Required",
|
||||||
|
"min": "Min",
|
||||||
|
"max": "Max",
|
||||||
|
"min_calc": "Min Calc",
|
||||||
|
"max_calc": "Max Calc",
|
||||||
|
"add_dependency": "Add Dependency",
|
||||||
|
"add_column": "Add Column",
|
||||||
|
"mode": "Mode",
|
||||||
|
"normal": "Normal",
|
||||||
|
"paperdb": "PaperDB",
|
||||||
|
"colordb": "ColorDB",
|
||||||
|
"container": "Container",
|
||||||
|
"edit_options": "Edit Options",
|
||||||
|
"add_option": "Add Option",
|
||||||
|
"close": "Close",
|
||||||
|
"dependencies": "Dependencies",
|
||||||
|
"options": "Options",
|
||||||
|
"settings": "Settings"
|
||||||
|
}
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
import { createI18n } from 'vue-i18n'
|
||||||
|
import de from './de.json'
|
||||||
|
import en from './en.json'
|
||||||
|
|
||||||
|
const i18n = createI18n({
|
||||||
|
legacy: false,
|
||||||
|
locale: 'de',
|
||||||
|
fallbackLocale: 'en',
|
||||||
|
messages: {
|
||||||
|
de,
|
||||||
|
en
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
export default i18n
|
||||||
@ -2,9 +2,11 @@ import { createApp } from 'vue'
|
|||||||
import './style.css'
|
import './style.css'
|
||||||
import { createPinia } from 'pinia'
|
import { createPinia } from 'pinia'
|
||||||
import App from './App.vue'
|
import App from './App.vue'
|
||||||
|
import i18n from './i18n'
|
||||||
|
|
||||||
const app = createApp(App)
|
const app = createApp(App)
|
||||||
|
|
||||||
app.use(createPinia())
|
app.use(createPinia())
|
||||||
|
app.use(i18n)
|
||||||
|
|
||||||
app.mount('#app')
|
app.mount('#app')
|
||||||
|
|||||||
@ -20,6 +20,10 @@ export default class BaseElement {
|
|||||||
isFocused: boolean = false;
|
isFocused: boolean = false;
|
||||||
dependencys: Dependency[] = [];
|
dependencys: Dependency[] = [];
|
||||||
|
|
||||||
|
hasDependencys() {
|
||||||
|
return this.dependencys.length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
toJSON() {
|
toJSON() {
|
||||||
return {
|
return {
|
||||||
'id': this.id,
|
'id': this.id,
|
||||||
|
|||||||
@ -7,6 +7,8 @@ export default class InputElement extends BaseElement {
|
|||||||
name: string = ""
|
name: string = ""
|
||||||
xmlType: string = "input"
|
xmlType: string = "input"
|
||||||
minValue: number = 0
|
minValue: number = 0
|
||||||
|
minCalc: string = ""
|
||||||
|
maxCalc: string = ""
|
||||||
maxValue: number = 0
|
maxValue: number = 0
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
@ -22,7 +24,9 @@ export default class InputElement extends BaseElement {
|
|||||||
'default': this.default,
|
'default': this.default,
|
||||||
'name': this.name,
|
'name': this.name,
|
||||||
'minValue': this.minValue,
|
'minValue': this.minValue,
|
||||||
|
'minCalc': this.minCalc,
|
||||||
'maxValue': this.maxValue,
|
'maxValue': this.maxValue,
|
||||||
|
'maxCalc': this.maxCalc,
|
||||||
'required': this.required
|
'required': this.required
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -34,6 +38,8 @@ export default class InputElement extends BaseElement {
|
|||||||
this.required = obj.required
|
this.required = obj.required
|
||||||
this.placeHolder = obj.placeHolder
|
this.placeHolder = obj.placeHolder
|
||||||
this.minValue = obj.minValue
|
this.minValue = obj.minValue
|
||||||
|
this.minCalc = obj.minCalc
|
||||||
this.maxValue = obj.maxValue
|
this.maxValue = obj.maxValue
|
||||||
|
this.maxCalc = obj.maxCalc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,6 +17,17 @@ export default class SelectElement extends BaseElement {
|
|||||||
this.options.push(option)
|
this.options.push(option)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hasDependencys() {
|
||||||
|
let hasDep = this.options.reduce((result: bool, opt: Option) => {
|
||||||
|
if(opt.dependencys.length > 0) {
|
||||||
|
result = true
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}, false)
|
||||||
|
|
||||||
|
return hasDep || super.hasDependencys()
|
||||||
|
}
|
||||||
|
|
||||||
public toJSON() {
|
public toJSON() {
|
||||||
return Object.assign(
|
return Object.assign(
|
||||||
super.toJSON(),
|
super.toJSON(),
|
||||||
|
|||||||
@ -2,7 +2,7 @@ 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'
|
||||||
import { loadJsonFromApi } from '../lib/api'
|
import { loadJsonFromApi, loadPriceFromApi } from '../lib/api'
|
||||||
|
|
||||||
|
|
||||||
export const useElementStore = defineStore('items', {
|
export const useElementStore = defineStore('items', {
|
||||||
@ -10,12 +10,17 @@ export const useElementStore = defineStore('items', {
|
|||||||
uuid: uuidv4(),
|
uuid: uuidv4(),
|
||||||
items: [] as BaseElement[],
|
items: [] as BaseElement[],
|
||||||
activeItem: {} as BaseElement | {},
|
activeItem: {} as BaseElement | {},
|
||||||
|
formulaData: [],
|
||||||
|
formulaError: '',
|
||||||
|
isFormulaLoading: false,
|
||||||
showProperties: false,
|
showProperties: false,
|
||||||
showDependency: false,
|
showDependency: false,
|
||||||
|
showOptions: false,
|
||||||
showPreview: false,
|
showPreview: false,
|
||||||
sourceDragUuid: "",
|
sourceDragUuid: "",
|
||||||
dragMode: "",
|
dragMode: "",
|
||||||
json: "",
|
json: "",
|
||||||
|
xml: "",
|
||||||
name: uuidv4(),
|
name: uuidv4(),
|
||||||
}),
|
}),
|
||||||
getters: {
|
getters: {
|
||||||
@ -24,9 +29,11 @@ export const useElementStore = defineStore('items', {
|
|||||||
getActiveItem: (state) => state.activeItem as BaseElement,
|
getActiveItem: (state) => state.activeItem as BaseElement,
|
||||||
isShowPropierties: (state) => state.showProperties,
|
isShowPropierties: (state) => state.showProperties,
|
||||||
isShowDependency: (state) => state.showDependency,
|
isShowDependency: (state) => state.showDependency,
|
||||||
|
isShowOptions: (state) => state.showOptions,
|
||||||
isShowPreview: (state) => state.showPreview,
|
isShowPreview: (state) => state.showPreview,
|
||||||
getSourceDragUuid: (state) => state.sourceDragUuid,
|
getSourceDragUuid: (state) => state.sourceDragUuid,
|
||||||
getDragMode: (state) => state.dragMode,
|
getDragMode: (state) => state.dragMode,
|
||||||
|
getFormulaData: (state) => state.formulaData,
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
addElement(item: BaseElement) {
|
addElement(item: BaseElement) {
|
||||||
@ -73,6 +80,9 @@ export const useElementStore = defineStore('items', {
|
|||||||
setShowDependency(value: boolean) {
|
setShowDependency(value: boolean) {
|
||||||
this.showDependency = value
|
this.showDependency = value
|
||||||
},
|
},
|
||||||
|
setShowOptions(value: boolean) {
|
||||||
|
this.showOptions = value
|
||||||
|
},
|
||||||
setShowProperties(value: boolean) {
|
setShowProperties(value: boolean) {
|
||||||
this.showProperties = value
|
this.showProperties = value
|
||||||
},
|
},
|
||||||
@ -140,10 +150,31 @@ export const useElementStore = defineStore('items', {
|
|||||||
setDragMode(mode: string) {
|
setDragMode(mode: string) {
|
||||||
this.dragMode = mode
|
this.dragMode = mode
|
||||||
},
|
},
|
||||||
async loadFromApi(id: string) {
|
async loadConfigFromProductApi(uuid: string) {
|
||||||
const data = await loadJsonFromApi(id);
|
const data = await loadJsonFromApi(uuid);
|
||||||
this.json = data;
|
this.json = data.json;
|
||||||
|
this.xml = data.xml;
|
||||||
this.parseJSON();
|
this.parseJSON();
|
||||||
|
},
|
||||||
|
async loadFormulaAnalyserDataFromApi(uuid: string) {
|
||||||
|
if (this.formulaData && this.formulaData.length > 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.isFormulaLoading = true;
|
||||||
|
this.formulaError = '';
|
||||||
|
try {
|
||||||
|
const response = await loadPriceFromApi(uuid);
|
||||||
|
if (response && response.debug && response.debug.graphJson) {
|
||||||
|
this.formulaData = JSON.parse(response.debug.graphJson);
|
||||||
|
} else {
|
||||||
|
throw new Error('Invalid or empty response format from API.');
|
||||||
|
}
|
||||||
|
} catch (e: any) {
|
||||||
|
this.formulaError = `Failed to load formula data: ${e.message}`;
|
||||||
|
console.error(e);
|
||||||
|
} finally {
|
||||||
|
this.isFormulaLoading = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,7 +29,7 @@ export default defineConfig({
|
|||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
configure: (proxy, options) => {
|
configure: (proxy, options) => {
|
||||||
proxy.on('proxyReq', (proxyReq, req, res) => {
|
proxy.on('proxyReq', (proxyReq, req, res) => {
|
||||||
proxyReq.setHeader('Authorization', 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE3NTI1MTE3MTgsImV4cCI6MTc1MjUxNTMxOCwicm9sZXMiOlsiUk9MRV9BRE1JTiIsIlJPTEVfU0hPUF9PUEVSQVRPUiIsIlJPTEVfVVNFUiIsIlJPTEVfVVNFUiIsIlJPTEVfUFNDX0NvbGxlY3RfQ29udGFjdF9FZGl0IiwiUk9MRV9QU0NfQ29sbGVjdF9Db250YWN0X0FkZCIsIlJPTEVfUFNDX0NvbGxlY3RfQ29udGFjdF9EZWxldGUiLCJST0xFX1BTQ19Db2xsZWN0X0NvbnRhY3RfTG9jayIsIlJPTEVfUFNDX1IyX1NlbmRjbG91ZF9TaG93Il0sInVpZCI6MX0.MlNFnqbWlCbaKejkcJgnri2d4pg569vfk6TrOe32rJbyyyb0X3svfhzvCsyO9i1-XwR0frm5s2fHdeGEumCjtel9VzLLIvbmr43NhUVPA03EG17pAX4QnM-GaL9vzIeZQlrIcwSprFKz9qo6Toc1Wq0mFEjvTwHj5UR5JBIgnV7TtScIVl83XJljMUbX-NrUSoOeGn6W2SRtH_bDP47ZC-P4wtDcXcrJWM9ka1Vknn-1DQgitVLtOEsxzU7bkxPpfC_ENuRqDE8HmpPZsizF4Pt9jzfAXcPy0CviBJxvg1-tu57h164VSsnz1-K6duBMTB18afi987-dXtBc7nKJhQ');
|
proxyReq.setHeader('Authorization', 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE3NTI1Nzc2NzIsImV4cCI6MTc1MjU4MTI3Miwicm9sZXMiOlsiUk9MRV9BRE1JTiIsIlJPTEVfU0hPUF9PUEVSQVRPUiIsIlJPTEVfVVNFUiIsIlJPTEVfVVNFUiIsIlJPTEVfUFNDX0NvbGxlY3RfQ29udGFjdF9FZGl0IiwiUk9MRV9QU0NfQ29sbGVjdF9Db250YWN0X0FkZCIsIlJPTEVfUFNDX0NvbGxlY3RfQ29udGFjdF9EZWxldGUiLCJST0xFX1BTQ19Db2xsZWN0X0NvbnRhY3RfTG9jayIsIlJPTEVfUFNDX1IyX1NlbmRjbG91ZF9TaG93Il0sInVpZCI6MX0.ViKfV_6cSsP6UvqibTJ5zXE8F5JZWmOEhNquw5_3bpB5N7rOtTIM8ZaD5i9VfoRf2a1CaSIKAzhte_8K49bNIpMd4B8mh3ufqUIHn33L34TsiTNblKv4PlQB_FZbCgujzfP2UenrDi3SAsHd5bynZUOJNbkGzMtv2sUot-mrKJmUvchl-yvcSFw4bYfy-88hnfXJ6sCDlIU-Vd9OSChoBqD12z3Nr6fEqY-ngq7Xv315yFY9Fhg3gxu5NqyAMzN-F6QJHjUsHlo2b9oLeAo2nFZ_Cj2nAMVa6VbxAXMrj6Ogf2POr1TWtvBBaJZj4c1D5rWktkFkPLTUAStNOwMRvQ');
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -89,6 +89,6 @@ class Config extends AbstractController
|
|||||||
$engine->setActiveArticle($data->xmlProduct);
|
$engine->setActiveArticle($data->xmlProduct);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->json($engine->generateJson());
|
return $this->json(['json' => $engine->generateJson(), 'xml' => $engine->generateXML(true)]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,96 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Plugin\System\PSC\XmlCalc\Api\Product;
|
||||||
|
|
||||||
|
use Doctrine\ODM\MongoDB\DocumentManager;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Nelmio\ApiDocBundle\Annotation\Model;
|
||||||
|
use Nelmio\ApiDocBundle\Annotation\Security;
|
||||||
|
use OpenApi\Annotations as OA;
|
||||||
|
use Plugin\System\PSC\XmlCalc\Dto\Input\DesignInput;
|
||||||
|
use Plugin\System\PSC\XmlCalc\Model\Product as PluginProduct;
|
||||||
|
use PSC\Component\ApiBundle\Dto\Error\NotFound;
|
||||||
|
use PSC\Library\Calc\Engine;
|
||||||
|
use PSC\Library\Calc\PaperContainer;
|
||||||
|
use PSC\Shop\ContactBundle\Model\Contact;
|
||||||
|
use PSC\Shop\ContactBundle\Transformer\Model\Contact as ContactTransformer;
|
||||||
|
use PSC\Shop\EntityBundle\Entity\Product;
|
||||||
|
use PSC\System\SettingsBundle\Service\PaperDB;
|
||||||
|
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
|
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
|
||||||
|
|
||||||
|
class Design extends AbstractController
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
private \PSC\System\SettingsBundle\Service\Shop $shopService,
|
||||||
|
private DocumentManager $documentManager,
|
||||||
|
private PaperDB $paperDB,
|
||||||
|
private ContactTransformer $contactTransformer,
|
||||||
|
private TokenStorageInterface $tokenStorage,
|
||||||
|
private EntityManagerInterface $entityManager,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="get config for product",
|
||||||
|
* @OA\JsonContent(ref=@Model(type=\Plugin\System\PSC\XmlCalc\Model\Product::class))
|
||||||
|
* )
|
||||||
|
* @OA\RequestBody(
|
||||||
|
*
|
||||||
|
* @Model(type=\Plugin\System\PSC\XmlCalc\Dto\Input\DesignInput::class))
|
||||||
|
* )
|
||||||
|
* @OA\Tag(name="Plugin/System/psc/Xmlcalc/Product")
|
||||||
|
* */
|
||||||
|
#[Route(path: '/product/design', methods: ['POST'])]
|
||||||
|
#[ParamConverter(
|
||||||
|
'data',
|
||||||
|
class: '\Plugin\System\PSC\XmlCalc\Dto\Input\DesignInput',
|
||||||
|
converter: 'psc_rest.request_body',
|
||||||
|
)]
|
||||||
|
public function config(DesignInput $data)
|
||||||
|
{
|
||||||
|
$product = $this->entityManager
|
||||||
|
->getRepository('PSC\Shop\EntityBundle\Entity\Product')
|
||||||
|
->findOneBy(['uuid' => $data->product]);
|
||||||
|
|
||||||
|
$paperContainer = new PaperContainer();
|
||||||
|
$paperContainer->parse(simplexml_load_string($product->getShop()->getInstall()->getPaperContainer()));
|
||||||
|
$engine = new Engine();
|
||||||
|
$engine->setPaperRepository($this->paperDB);
|
||||||
|
$engine->setPaperContainer($paperContainer);
|
||||||
|
if ($product->getShop()->getInstall()->getCalcTemplates() && !$data->test) {
|
||||||
|
$engine->setTemplates('<root>' . $product->getShop()->getInstall()->getCalcTemplates() . '</root>');
|
||||||
|
}
|
||||||
|
if ($product->getShop()->getInstall()->getCalcTemplatesTest() && $data->test) {
|
||||||
|
$engine->setTemplates('<root>' . $product->getShop()->getInstall()->getCalcTemplatesTest() . '</root>');
|
||||||
|
}
|
||||||
|
$engine->loadJson($data->jsonProduct);
|
||||||
|
if (!$data->test) {
|
||||||
|
$engine->setFormulas($product->getShop()->getFormel());
|
||||||
|
$engine->setParameters($product->getShop()->getParameter());
|
||||||
|
}
|
||||||
|
if ($data->test) {
|
||||||
|
$engine->setFormulas($product->getShop()->getTestFormel());
|
||||||
|
$engine->setParameters($product->getShop()->getTestParameter());
|
||||||
|
}
|
||||||
|
$engine->setVariables($data->values);
|
||||||
|
$engine->setTax($product->getMwert());
|
||||||
|
if ($this->tokenStorage->getToken()) {
|
||||||
|
$contact = new Contact();
|
||||||
|
$this->contactTransformer->fromDb($contact, $this->tokenStorage->getToken()->getUser());
|
||||||
|
$engine->setVariable('contact.accountType', $contact->getAccountType()->value);
|
||||||
|
$engine->setVariable('contact.account', $contact->getAccount()->getUid());
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->json([
|
||||||
|
'json' => $engine->generateJson(),
|
||||||
|
'xml' => $engine->generateXML(true),
|
||||||
|
'jsonGraph' => $engine->getCalcGraph()->generateJsonGraph(),
|
||||||
|
'price' => $engine->getPrice() * 100,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Plugin\System\PSC\XmlCalc\Dto\Input;
|
||||||
|
|
||||||
|
use Nelmio\ApiDocBundle\Annotation\Model;
|
||||||
|
use OpenApi\Annotations as OA;
|
||||||
|
|
||||||
|
final class DesignInput
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*
|
||||||
|
* @OA\Property(type="string")
|
||||||
|
*/
|
||||||
|
public string $product;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*
|
||||||
|
* @OA\Property(type="string")
|
||||||
|
*/
|
||||||
|
public string $jsonProduct = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool
|
||||||
|
*
|
||||||
|
* @OA\Property(type="boolean")
|
||||||
|
*/
|
||||||
|
public bool $test = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*
|
||||||
|
* @OA\Property(type="array", @OA\Items(type="string"))
|
||||||
|
*/
|
||||||
|
public array $values = ['auflage' => 100];
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user