This commit is contained in:
Thomas Peterson 2025-08-07 22:19:51 +02:00
parent 059c62459e
commit 3f1d28b9da
10 changed files with 98 additions and 65 deletions

View File

@ -1,17 +1,18 @@
<script setup lang="ts"> <script lang="ts" setup>
import { computed, watch } from 'vue' import { computed } from 'vue';
import { useGlobalStore } from '../../../stores/Global' import { useGlobalStore } from '../../../stores/Global';
import { Codemirror } from 'vue-codemirror' import RenderElements from './RenderElements.vue';
import { json } from '@codemirror/lang-json'
import RenderElements from './RenderElements.vue'
import PriceDisplay from './PriceDisplay.vue'; import PriceDisplay from './PriceDisplay.vue';
const globalStore = useGlobalStore() import type { PreviewResponse } from '../../../model/preview/types';
const previewData = computed(() => globalStore.getPreviewData) const globalStore = useGlobalStore();
const error = computed(() => globalStore.previewError)
const isLoading = computed(() => globalStore.isPreviewLoading)
const items = computed(() => previewData.value?.elements || []) const previewData = computed<PreviewResponse | null>(() => globalStore.getPreviewData);
const error = computed(() => globalStore.previewError);
const isLoading = computed(() => globalStore.isPreviewLoading);
const items = computed(() => previewData.value?.elements || []);
const price = computed(() => previewData.value);
</script> </script>
@ -33,7 +34,7 @@ const items = computed(() => previewData.value?.elements || [])
<RenderElements :items="items"/> <RenderElements :items="items"/>
</div> </div>
<div class="w-2/5 pl-6"> <div class="w-2/5 pl-6">
<PriceDisplay :tax="previewData.tax" :brutto="previewData.brutto" :netto="previewData.netto" /> <PriceDisplay :price-data="price" />
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,19 +1,18 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed } from 'vue'; import { computed } from 'vue';
import type { PreviewResponse } from '../../../model/preview/types';
const props = defineProps<{ const props = defineProps<{
netto: any; priceData: PreviewResponse | null;
tax: any;
brutto: any;
}>(); }>();
const formatCurrency = (value: number) => { const formatCurrency = (value: number) => {
return new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(value); return new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(value);
}; };
const netPrice = computed(() => formatCurrency(props.netto/100 || 0)); const netPrice = computed(() => formatCurrency(props.priceData?.netto / 100 || 0));
const tax = computed(() => formatCurrency(props.tax/100 || 0)); const tax = computed(() => formatCurrency(props.priceData?.tax / 100 || 0));
const grossPrice = computed(() => formatCurrency(props.brutto/100 || 0)); const grossPrice = computed(() => formatCurrency(props.priceData?.brutto / 100 || 0));
</script> </script>

View File

@ -1,38 +1,34 @@
<script lang="ts" setup> <script lang="ts" setup>
import { computed } from 'vue'; import { shallowRef } from 'vue';
import TextElement from './elements/TextElement.vue' import type { Component } from 'vue';
import InputElement from './elements/InputElement.vue' import type { PreviewElement } from '../../../model/preview/types';
import HiddenElement from './elements/HiddenElement.vue'
import HeadlineElement from './elements/HeadlineElement.vue' import TextElement from './elements/TextElement.vue';
import SelectElement from './elements/SelectElement.vue' import InputElement from './elements/InputElement.vue';
import HiddenElement from './elements/HiddenElement.vue';
import HeadlineElement from './elements/HeadlineElement.vue';
import SelectElement from './elements/SelectElement.vue';
const props = defineProps<{ const props = defineProps<{
items: any items: PreviewElement[]
}>() }>();
const componentMap: Record<string, Component> = shallowRef({
headline: HeadlineElement,
text: TextElement,
input: InputElement,
hidden: HiddenElement,
select: SelectElement,
});
</script> </script>
<template> <template>
<div class="d-flex flex flex-col relative" v-for="item in items" v-if="items.length > 0" :key="item.uuid"> <div v-for="item in items" :key="item.id">
<HeadlineElement <component
v-if="item.valid && item.htmlType === 'headline'" v-if="item.valid && componentMap[item.htmlType]"
:item="item" :is="componentMap[item.htmlType]"
/> :item="item"
<HiddenElement />
v-if="item.valid && item.htmlType === 'hidden'"
:item="item"
/>
<InputElement
v-if="item.valid && item.htmlType === 'input'"
:item="item"
/>
<TextElement
v-if="item.valid && item.htmlType === 'text'"
:item="item"
/>
<SelectElement
v-if="item.valid && item.htmlType === 'select'"
:item="item"
/>
</div> </div>
</template> </template>

View File

@ -1,8 +1,8 @@
<script lang="ts" setup> <script lang="ts" setup>
import { computed } from 'vue'; import type { PreviewElement } from '../../../../model/preview/types';
const props = defineProps<{ const props = defineProps<{
item: any item: PreviewElement
}>() }>()
</script> </script>

View File

@ -1,9 +1,9 @@
<script lang="ts" setup> <script lang="ts" setup>
import { computed } from 'vue'; import type { PreviewElement } from '../../../../model/preview/types';
import { Input } from '../../../../components/ui/input' import { Input } from '../../../../components/ui/input';
const props = defineProps<{ const props = defineProps<{
item: any item: PreviewElement
}>() }>()

View File

@ -1,13 +1,11 @@
<script lang="ts" setup> <script lang="ts" setup>
import { computed } from 'vue'; import type { PreviewElement } from '../../../../model/preview/types';
import { Input } from '../../../../components/ui/input' import { Input } from '../../../../components/ui/input';
import { useGlobalStore } from '../../../../stores/Global'
const props = defineProps<{ const props = defineProps<{
item: any item: PreviewElement
}>() }>()
const globalStore = useGlobalStore()
</script> </script>

View File

@ -1,5 +1,5 @@
<script lang="ts" setup> <script lang="ts" setup>
import { computed } from 'vue' import type { PreviewElement } from '../../../../model/preview/types';
import { import {
Select, Select,
SelectContent, SelectContent,
@ -7,10 +7,10 @@ import {
SelectItem, SelectItem,
SelectTrigger, SelectTrigger,
SelectValue, SelectValue,
} from '../../../../components/ui/select' } from '../../../../components/ui/select';
const props = defineProps<{ const props = defineProps<{
item: any item: PreviewElement
}>() }>()
</script> </script>

View File

@ -1,8 +1,8 @@
<script lang="ts" setup> <script lang="ts" setup>
import { computed } from 'vue'; import type { PreviewElement } from '../../../../model/preview/types';
const props = defineProps<{ const props = defineProps<{
item: any item: PreviewElement
}>() }>()
</script> </script>

View File

@ -0,0 +1,38 @@
export interface PreviewOption {
id: string;
name: string;
valid: boolean;
selected: boolean;
}
export interface PreviewElement {
id: string;
name: string;
pattern: string;
colorSystem: string;
placeHolder: string;
displayGroup: string;
defaultValue: string;
value: string;
help: string | null;
helpLink: string | null;
valid: boolean;
required: boolean;
rawValue: string;
rawValues: any[];
options: PreviewOption[];
htmlType: 'headline' | 'text' | 'input' | 'hidden' | 'select';
validationErrors: any[];
variant?: string; // For headline
minValue?: number; // For input
maxValue?: number; // For input
}
export interface PreviewResponse {
success: boolean;
netto: number;
tax: number;
brutto: number;
colorDb: any[];
elements: PreviewElement[];
}

View File

@ -1,6 +1,7 @@
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import BaseElement from '../model/BaseElement' import BaseElement from '../model/BaseElement'
import Mode from '../model/Mode' import Mode from '../model/Mode'
import type { PreviewResponse } from '../model/preview/types';
import { saveProductToApi, saveFomulasAndParameterToApi, loadJsonFromApi, loadPriceFromApi, savePaperContainerToApi, saveDesignToApi, saveXmlToApi, fetchPreview } from '../lib/api' import { saveProductToApi, saveFomulasAndParameterToApi, loadJsonFromApi, loadPriceFromApi, savePaperContainerToApi, saveDesignToApi, saveXmlToApi, fetchPreview } from '../lib/api'
import { useItemStore } from './Items' import { useItemStore } from './Items'
@ -29,7 +30,7 @@ export const useGlobalStore = defineStore('global', {
saving: false, saving: false,
syncing: false, syncing: false,
currentTab: 'designer' as string | number, currentTab: 'designer' as string | number,
previewData: {} as object, previewData: null as PreviewResponse | null,
isPreviewLoading: false, isPreviewLoading: false,
previewError: '', previewError: '',
}), }),
@ -44,7 +45,7 @@ export const useGlobalStore = defineStore('global', {
getDragMode: (state) => state.dragMode, getDragMode: (state) => state.dragMode,
getFormulaData: (state) => state.formulaData, getFormulaData: (state) => state.formulaData,
getFormulaError: (state) => state.formulaError, getFormulaError: (state) => state.formulaError,
getPreviewData: (state) => state.previewData, getPreviewData: (state) => state.previewData as PreviewResponse | null,
}, },
actions: { actions: {
setXml(value: string) { setXml(value: string) {