mirror of
https://github.com/duhanbalci/dreport.git
synced 2026-07-01 18:39:16 +00:00
206 lines
6.8 KiB
Vue
206 lines
6.8 KiB
Vue
<script setup lang="ts">
|
|
import { computed } from 'vue'
|
|
import { useTemplateStore } from '../../stores/template'
|
|
import { useEditorStore } from '../../stores/editor'
|
|
import { isContainer } from '../../core/types'
|
|
import type {
|
|
ContainerElement,
|
|
LineElement,
|
|
ImageElement,
|
|
PageNumberElement,
|
|
BarcodeElement,
|
|
RepeatingTableElement,
|
|
CurrentDateElement,
|
|
ShapeElement,
|
|
CheckboxElement,
|
|
CalculatedTextElement,
|
|
RichTextElement,
|
|
ChartElement,
|
|
} from '../../core/types'
|
|
import PositioningProperties from '../properties/PositioningProperties.vue'
|
|
import SizeProperties from '../properties/SizeProperties.vue'
|
|
import TextProperties from '../properties/TextProperties.vue'
|
|
import LineProperties from '../properties/LineProperties.vue'
|
|
import ImageProperties from '../properties/ImageProperties.vue'
|
|
import PageNumberProperties from '../properties/PageNumberProperties.vue'
|
|
import BarcodeProperties from '../properties/BarcodeProperties.vue'
|
|
import CurrentDateProperties from '../properties/CurrentDateProperties.vue'
|
|
import ShapeProperties from '../properties/ShapeProperties.vue'
|
|
import CheckboxProperties from '../properties/CheckboxProperties.vue'
|
|
import CalculatedTextProperties from '../properties/CalculatedTextProperties.vue'
|
|
import RichTextProperties from '../properties/RichTextProperties.vue'
|
|
import ContainerProperties from '../properties/ContainerProperties.vue'
|
|
import RepeatingTableProperties from '../properties/RepeatingTableProperties.vue'
|
|
import ChartProperties from '../properties/ChartProperties.vue'
|
|
import '../../styles/properties.css'
|
|
|
|
const templateStore = useTemplateStore()
|
|
const editorStore = useEditorStore()
|
|
|
|
const selectedElement = computed(() => {
|
|
const id = editorStore.selectedElementId
|
|
if (!id) return null
|
|
return templateStore.getElementById(id) ?? null
|
|
})
|
|
|
|
const elementTypeLabel = computed(() => {
|
|
const el = selectedElement.value
|
|
if (!el) return ''
|
|
switch (el.type) {
|
|
case 'container':
|
|
if (el.id === 'header') return 'Üst Bilgi'
|
|
if (el.id === 'footer') return 'Alt Bilgi'
|
|
return 'Container'
|
|
case 'static_text': return 'Metin'
|
|
case 'text': return 'Metin'
|
|
case 'line': return 'Cizgi'
|
|
case 'repeating_table': return 'Tablo'
|
|
case 'image': return 'Gorsel'
|
|
case 'page_number': return 'Sayfa No'
|
|
case 'barcode': return 'Barkod'
|
|
case 'checkbox': return 'Onay Kutusu'
|
|
case 'shape': return 'Sekil'
|
|
case 'current_date': return 'Tarih'
|
|
case 'calculated_text': return 'Hesaplanan Metin'
|
|
case 'rich_text': return 'Zengin Metin'
|
|
case 'page_break': return 'Sayfa Sonu'
|
|
case 'chart': return 'Grafik'
|
|
default: return 'Eleman'
|
|
}
|
|
})
|
|
|
|
function toggleHeader(e: Event) {
|
|
const checked = (e.target as HTMLInputElement).checked
|
|
if (checked) templateStore.enableHeader()
|
|
else templateStore.disableHeader()
|
|
}
|
|
|
|
function toggleFooter(e: Event) {
|
|
const checked = (e.target as HTMLInputElement).checked
|
|
if (checked) templateStore.enableFooter()
|
|
else templateStore.disableFooter()
|
|
}
|
|
|
|
function deleteElement() {
|
|
const id = editorStore.selectedElementId
|
|
if (!id || id === 'root') return
|
|
editorStore.clearSelection()
|
|
templateStore.removeElement(id)
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="properties-panel">
|
|
<div v-if="!selectedElement" class="properties-panel__empty">
|
|
Bir eleman secin
|
|
</div>
|
|
|
|
<template v-else>
|
|
<!-- Header -->
|
|
<div class="prop-section">
|
|
<div class="prop-section__title">
|
|
{{ elementTypeLabel }}
|
|
<span class="prop-id">{{ selectedElement.id }}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Page break: minimal info, just delete -->
|
|
<template v-if="selectedElement.type === 'page_break'">
|
|
<div class="prop-section">
|
|
<button class="prop-delete-btn" @click="deleteElement">Sil</button>
|
|
</div>
|
|
</template>
|
|
|
|
<template v-else>
|
|
<PositioningProperties :element="selectedElement" />
|
|
<SizeProperties :element="selectedElement" />
|
|
|
|
<TextProperties
|
|
v-if="selectedElement.type === 'static_text' || selectedElement.type === 'text'"
|
|
:element="selectedElement" />
|
|
|
|
<LineProperties
|
|
v-if="selectedElement.type === 'line'"
|
|
:element="(selectedElement as LineElement)" />
|
|
|
|
<ImageProperties
|
|
v-if="selectedElement.type === 'image'"
|
|
:element="(selectedElement as ImageElement)" />
|
|
|
|
<PageNumberProperties
|
|
v-if="selectedElement.type === 'page_number'"
|
|
:element="(selectedElement as PageNumberElement)" />
|
|
|
|
<BarcodeProperties
|
|
v-if="selectedElement.type === 'barcode'"
|
|
:element="(selectedElement as BarcodeElement)" />
|
|
|
|
<CurrentDateProperties
|
|
v-if="selectedElement.type === 'current_date'"
|
|
:element="(selectedElement as CurrentDateElement)" />
|
|
|
|
<CheckboxProperties
|
|
v-if="selectedElement.type === 'checkbox'"
|
|
:element="(selectedElement as CheckboxElement)" />
|
|
|
|
<CalculatedTextProperties
|
|
v-if="selectedElement.type === 'calculated_text'"
|
|
:element="(selectedElement as CalculatedTextElement)" />
|
|
|
|
<RichTextProperties
|
|
v-if="selectedElement.type === 'rich_text'"
|
|
:element="(selectedElement as RichTextElement)" />
|
|
|
|
<ShapeProperties
|
|
v-if="selectedElement.type === 'shape'"
|
|
:element="(selectedElement as ShapeElement)" />
|
|
|
|
<ContainerProperties
|
|
v-if="isContainer(selectedElement)"
|
|
:element="(selectedElement as ContainerElement)" />
|
|
|
|
<RepeatingTableProperties
|
|
v-if="selectedElement.type === 'repeating_table'"
|
|
:element="(selectedElement as RepeatingTableElement)" />
|
|
|
|
<ChartProperties
|
|
v-if="selectedElement.type === 'chart'"
|
|
:element="(selectedElement as ChartElement)" />
|
|
|
|
<!-- Header/Footer toggles for root element -->
|
|
<div v-if="selectedElement.id === 'root'" class="prop-section">
|
|
<div class="prop-section__title">Sayfa Ust/Alt Bilgi</div>
|
|
<div class="prop-row">
|
|
<label class="prop-label">Ust Bilgi (Header)</label>
|
|
<input type="checkbox" :checked="!!templateStore.template.header"
|
|
@change="toggleHeader" />
|
|
</div>
|
|
<div class="prop-row">
|
|
<label class="prop-label">Alt Bilgi (Footer)</label>
|
|
<input type="checkbox" :checked="!!templateStore.template.footer"
|
|
@change="toggleFooter" />
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Delete -->
|
|
<div v-if="selectedElement.id !== 'root'" class="prop-section">
|
|
<button class="prop-delete-btn" @click="deleteElement">Sil</button>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.properties-panel {
|
|
padding: 12px;
|
|
}
|
|
|
|
.properties-panel__empty {
|
|
color: #94a3b8;
|
|
font-size: 13px;
|
|
text-align: center;
|
|
margin-top: 40px;
|
|
}
|
|
</style>
|