/** * Liste görünümlerinde (grid hücresi, image upload/viewer editörleri) kullanılan * ortak görsel değer normalizasyon yardımcıları. * * Daha önce useListFormColumns.ts, ImageViewerEditorComponent.tsx ve * ImageUploadEditorComponent.tsx içinde birebir tekrarlanıyordu. */ export const NO_IMAGE = '/img/others/no-image.png' /** String ya da obje olabilen bir değeri düz objeye çevirir; dizi/geçersiz JSON için undefined döner. */ export const parseJsonObject = (value: unknown): Record | undefined => { if (!value) return undefined if (typeof value === 'object') { return Array.isArray(value) ? undefined : (value as Record) } if (typeof value !== 'string') return undefined try { const parsed = JSON.parse(value) return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? (parsed as Record) : undefined } catch { return undefined } } /** Pozitif sayıya çevirir, aksi halde varsayılanı döner. */ export const normalizeImageSize = (value: unknown, fallback: number) => { const size = Number(value) return Number.isFinite(size) && size > 0 ? size : fallback } /** Obje formatındaki görsel değerinden (url/src/fileUrl/path/value) kaynağı çıkarır. */ export const getImageSource = (value: unknown) => { if (!value) return '' if (typeof value === 'string') return value.trim() if (typeof value === 'object') { const item = value as Record return String(item.url ?? item.src ?? item.fileUrl ?? item.path ?? item.value ?? '').trim() } return String(value).trim() } const isProbablyBase64Image = (value: string) => value.length > 80 && /^[A-Za-z0-9+/]+={0,2}$/.test(value) /** Ham base64 içeriğini data URL'e çevirir; zaten URL ise dokunmaz. */ export const toImageSource = (value: string) => { const trimmed = value.trim() if (!trimmed) return '' if (trimmed.startsWith('data:image/') || !isProbablyBase64Image(trimmed)) return trimmed return `data:image/jpeg;base64,${trimmed}` } const splitImageString = (value: string) => { const trimmed = value.trim() if (!trimmed) return [] if (trimmed.startsWith('data:image/')) return [trimmed] return trimmed .split(/\r?\n|\|\s*/) .flatMap((part) => { const text = part.trim() if (!text || text.startsWith('data:image/')) return text ? [text] : [] return text.split(',').map((item) => item.trim()) }) .map(toImageSource) .filter(Boolean) } /** * Tek görsel, çoklu görsel, JSON dizi ya da ayraçlı string olabilen değeri * gösterilebilir URL listesine dönüştürür. */ export const normalizeImageValue = (value: unknown): string[] => { if (Array.isArray(value)) { return value.flatMap((item) => normalizeImageValue(item)) } if (typeof value === 'string') { const trimmed = value.trim() if (!trimmed) return [] if (trimmed.startsWith('[')) { try { const parsed = JSON.parse(trimmed) if (Array.isArray(parsed)) { return parsed.flatMap((item) => normalizeImageValue(item)) } } catch { return [toImageSource(trimmed)] } } return splitImageString(trimmed) } const source = getImageSource(value) return source ? [toImageSource(source)] : [] } /** Kolon yapılandırmasından image upload/viewer seçeneklerini çözer. */ export const resolveImageColumnOptions = (column: unknown): Record => { const col = column as any const configured = col?.extras?.imageUploadOptions if (configured && Object.keys(configured).length > 0) { return configured } return parseJsonObject(col?.extras?.editorOptions) ?? parseJsonObject(col?.editorOptions) ?? {} }