improvements

This commit is contained in:
2026-03-29 13:40:16 +03:00
parent 9e13afaeae
commit 8560b40a64
29 changed files with 8422 additions and 465 deletions

View File

@@ -27,6 +27,16 @@ export const useEditorStore = defineStore('editor', () => {
zoom.value = Math.max(0.25, Math.min(4, value))
}
function setPan(x: number, y: number) {
panX.value = x
panY.value = y
}
function resetPan() {
panX.value = 0
panY.value = 0
}
function setDragging(value: boolean) {
isDragging.value = value
}
@@ -57,6 +67,8 @@ export const useEditorStore = defineStore('editor', () => {
selectElement,
clearSelection,
setZoom,
setPan,
resetPan,
setDragging,
startDragNewElement,
setDropTargetContainer,

View File

@@ -0,0 +1,111 @@
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import type { JsonSchema, SchemaNode } from '../core/schema-parser'
import { parseSchema, findArrayFields, findScalarFields } from '../core/schema-parser'
/** Varsayılan fatura schema'sı */
const defaultSchema: JsonSchema = {
$id: 'fatura-schema',
type: 'object',
properties: {
firma: {
type: 'object',
title: 'Firma',
properties: {
unvan: { type: 'string', title: 'Firma Unvani' },
vergiNo: { type: 'string', title: 'Vergi No' },
logo: { type: 'string', title: 'Logo', format: 'image' },
adres: { type: 'string', title: 'Adres' },
telefon: { type: 'string', title: 'Telefon' },
},
},
fatura: {
type: 'object',
title: 'Fatura',
properties: {
no: { type: 'string', title: 'Fatura No' },
tarih: { type: 'string', title: 'Tarih', format: 'date' },
},
},
musteri: {
type: 'object',
title: 'Musteri',
properties: {
unvan: { type: 'string', title: 'Musteri Unvani' },
vergiNo: { type: 'string', title: 'Vergi No' },
adres: { type: 'string', title: 'Adres' },
},
},
kalemler: {
type: 'array',
title: 'Fatura Kalemleri',
items: {
type: 'object',
properties: {
siraNo: { type: 'integer', title: 'Sira No' },
adi: { type: 'string', title: 'Urun / Hizmet Adi' },
miktar: { type: 'number', title: 'Miktar' },
birim: { type: 'string', title: 'Birim' },
birimFiyat: { type: 'number', title: 'Birim Fiyat', format: 'currency' },
tutar: { type: 'number', title: 'Tutar', format: 'currency' },
},
},
},
toplamlar: {
type: 'object',
title: 'Toplamlar',
properties: {
araToplam: { type: 'number', title: 'Ara Toplam', format: 'currency' },
kdv: { type: 'number', title: 'KDV', format: 'currency' },
genelToplam: { type: 'number', title: 'Genel Toplam', format: 'currency' },
},
},
},
}
export const useSchemaStore = defineStore('schema', () => {
const rawSchema = ref<JsonSchema>(defaultSchema)
const schemaTree = computed<SchemaNode>(() => parseSchema(rawSchema.value))
/** Tüm array alanları (tablo binding için) */
const arrayFields = computed(() => findArrayFields(schemaTree.value))
/** Tüm scalar alanlar (metin binding için) */
const scalarFields = computed(() => findScalarFields(schemaTree.value))
/** Schema'yı güncelle (ör: JSON import) */
function setSchema(schema: JsonSchema) {
rawSchema.value = schema
}
/** Belirli bir path'teki SchemaNode'u bul */
function getNodeByPath(path: string): SchemaNode | undefined {
return findNode(schemaTree.value, path)
}
/** Bir array alanının item property'lerini getir */
function getArrayItemFields(arrayPath: string): SchemaNode[] {
const node = findNode(schemaTree.value, arrayPath)
return node?.itemProperties ?? []
}
return {
rawSchema,
schemaTree,
arrayFields,
scalarFields,
setSchema,
getNodeByPath,
getArrayItemFields,
}
})
function findNode(node: SchemaNode, path: string): SchemaNode | undefined {
if (node.path === path) return node
for (const child of node.children) {
const found = findNode(child, path)
if (found) return found
}
return undefined
}

View File

@@ -2,7 +2,7 @@ import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import type { Template, TemplateElement, ContainerElement, SizeConstraint, PositionMode } from '../core/types'
import { findElementById, findParent, isContainer, sz } from '../core/types'
import { templateToTypst } from '../core/template-to-typst'
import { generateMockData } from '../core/mock-data-generator'
import { useUndoRedo } from '../composables/useUndoRedo'
function createDefaultTemplate(): Template {
@@ -47,7 +47,7 @@ function createDefaultTemplate(): Template {
export const useTemplateStore = defineStore('template', () => {
const template = ref<Template>(createDefaultTemplate())
const typstMarkup = computed(() => templateToTypst(template.value))
const mockData = computed(() => generateMockData(template.value))
// Undo / Redo
const { undo, redo, canUndo, canRedo } = useUndoRedo(template)
@@ -117,9 +117,25 @@ export const useTemplateStore = defineStore('template', () => {
parent.children.splice(toIndex, 0, moved)
}
/** Şablonu JSON olarak dışa aktar */
function exportTemplate(): string {
return JSON.stringify(template.value, null, 2)
}
/** JSON'dan şablon yükle */
function importTemplate(json: string) {
const parsed = JSON.parse(json) as Template
template.value = parsed
}
/** Yeni boş şablon oluştur */
function resetTemplate() {
template.value = createDefaultTemplate()
}
return {
template,
typstMarkup,
mockData,
getElementById,
getParent,
addChild,
@@ -129,6 +145,9 @@ export const useTemplateStore = defineStore('template', () => {
updateElementSize,
updateElement,
reorderChild,
exportTemplate,
importTemplate,
resetTemplate,
undo,
redo,
canUndo,