LivaTreeList
DevExtreme TreeList üzerine kurulu hiyerarşik veri tablosu. LivaDataGrid ile
aynı veri kaynağı desenini paylaşır; ek olarak keyExpr ve parentIdExpr
çifti ile düz bir diziden ağaç yapısı kurar. Özyinelemeli seçim, seçim özeti,
satır sürükleme ve satır içi düzenleme özellikleri hazırdır.
import { LivaTreeList, type LivaTreeListColumn } from "@dataliva/livalib";
Hiyerarşi
keyExpr her satırın anahtarını, parentIdExpr üst satırın anahtarını
gösterir. Kök satırlar burada parentId: 0 ile işaretlenir; bunu rootValue
ile açıkça bildirmek gerekir. LivaTreeList rootValue için varsayılan
atamaz — verilmezse hiçbir satır kök sayılmaz ve tablo "No data" görünür.
autoExpandAll tüm dalları açık başlatır. Kolonlar LivaTreeListColumn
tipindedir; sayısal biçimlendirme için customizeText kullanılabilir.
type Birim = { id: number; parentId: number; ad: string; yonetici: string; personel: number; butce: number };
const birimler: Birim[] = [
{ id: 1, parentId: 0, ad: "Genel Müdürlük", yonetici: "Ayşe Yılmaz", personel: 4, butce: 1200000 },
{ id: 2, parentId: 1, ad: "Finans", yonetici: "Mehmet Demir", personel: 12, butce: 420000 },
// ...
];
const kolonlar: LivaTreeListColumn[] = [
{ dataField: "ad", caption: "Birim" },
{ dataField: "yonetici", caption: "Yönetici" },
{ dataField: "personel", caption: "Personel", dataType: "number", alignment: "right", width: 110 },
{
dataField: "butce",
caption: "Bütçe",
dataType: "number",
alignment: "right",
customizeText: (c) => (typeof c.value === "number" ? c.value.toLocaleString("tr-TR") + " ₺" : ""),
},
];
Seçim
selectionMode varsayılanı 'multiple''dır: satır başına onay kutuları
kendiliğinden gelir. Seçim istemiyorsanız selectionMode="none" verin.
recursiveSelection bir üst düğüm seçildiğinde tüm alt düğümleri de seçer.
showSelectionSummary başlığın yanına seçili / toplam biçiminde bir KPI
pili ekler.
Seçim kontrollü çalışır: selectedRowKeys ile seçili anahtarları verip
onSelectionChanged içinde state'i güncellemek gerekir. Bu ikisi bağlanmazsa
onay kutuları görünür ama tıklama sonrası seçim geri alınır.
onSelectionChanged olayı DevExtreme alanlarına ek olarak
selectedRowKeysWithDescendants taşır: seçili düğümlerin tüm alt
anahtarlarını içerir. Bir üst düğüm seçildiğinde alt kayıtları tek istekte
çekmek için kullanılır (ör. loadUrl'e ccntId=1,2,3 göndermek).
Toplam kayıt satırı — totalRow
totalRow ağacın altına (alt araç çubuğunun üstüne) Toplam kayıt: N şeridini
ekler. Dizi kaynakta başlangıç değeri dizinin uzunluğudur; yani yalnızca kök
satırlar değil, açık ya da kapalı tüm düğümler sayılır. Ağaç içeriği her
hazırlandığında sayı veri kaynağının bildirdiği toplamla
(getDataSource().totalCount()) tazelenir; toplam alınamazsa son bilinen değer
kalır, hiç bilinmiyorsa — görünür. Etiket ve sayı biçimi lang'a göre seçilir
(EN… → Total records, aksi halde Toplam kayıt). Varsayılan false'tur.
Ortak prop preset'i — getTreeList()
getGridProps()'un ağaç karşılığı. Çoğu ağaçta tekrar eden temel propları tek
tek yazmak yerine projenin kendi preset fonksiyonunu spread edin:
import { LivaTreeList } from "@dataliva/livalib";
import { getTreeList } from "@/features/_shared/components";
<LivaTreeList
{...getTreeList()}
keyExpr="id"
parentIdExpr="parentId"
rootValue={0}
dataSource={birimler}
columns={kolonlar}
/>
Spread'i en başa koyun ki sayfaya özel proplar (ör. remoteOperations)
ezebilsin. Ağaç yapısı (keyExpr / parentIdExpr / rootValue), yetki
propları, export, veri kaynağı ve olaylar preset'e girmez; bunlar her
sayfanın kendi kararıdır.
Preset fonksiyonunu tanımlama
LivaBudget'ta _shared/components/getTreeList.ts altında durur:
import { LivaTreeList } from "@dataliva/livalib";
import type { ComponentProps } from "react";
type LivaTreeListProps = ComponentProps<typeof LivaTreeList>;
export function getTreeList(): Partial<LivaTreeListProps> {
return {
gridSize: "xxs",
fullHeight: true,
editMode: "batch",
scrollingMode: "virtual",
showToolbar: true,
showSearchPanel: true,
showColumnChooser: true,
isLivaContextMenu: true,
lang: currentLanguage(), // Accept-Language başlığı
noDataText: t("Common.NoData"), // çeviriden
};
}
getGridProps()'tan farkı: TreeList'te kolon seçici prop'u showColumnChooser
adıyla gelir (DataGrid'de columnChooser), ve allowGrouping yoktur.
Değerler mevcut kullanımların taranmasıyla seçilir: LivaBudget'taki 21
<LivaTreeList> kullanımında gridSize: "xxs" 20/20, fullHeight 19/19,
showSearchPanel 15/15, editMode: "batch" 10/10 çıktı.
Preset, bileşenin üç varsayılanını bilerek değiştirir: LivaTreeList'in kendi
showSearchPanel varsayılanı false, editMode varsayılanı 'row',
scrollingMode varsayılanı 'standard''dır.
Bu bir hook DEĞİLDİR ve hook çağırmaz.
getGridProps()ile aynı gerekçe: fonksiyon JSX içinde koşullu dallarda çağrılabildiği için hook barındırırsa render'lar arasında hook sayısı değişir ve React "Rendered more hooks than during the previous render" hatası verir. Dil ve çeviri değerlerini store'dan / i18n örneğinden doğrudan okuyun.
Kütüphane tarafı — baseTreeListProps
@dataliva/livalib, baseGridProps'un ağaç karşılığı olan asgari bir nesne de
dışa aktarır:
| Prop | Değer |
|---|---|
gridSize | "xs" |
fullHeight | true |
showToolbar | true |
showSearchPanel | true |
showColumnChooser | true |
editMode | "batch" |
Sayfalarda doğrudan spread etmeyin; yeni bir projede preset fonksiyonuna başlangıç noktası olarak kullanın. Ayrıntı: getGridProps() bölümü.
Toplu işlemler ve ondalık basamak
selectionMode="multiple" iken alt araç çubuğunda İşlemler menüsü çıkar
(bulkActions, bulkSelectionTools, allowBulkDelete, onBulkDelete).
Sayısal kolonlara sağ tıklandığında Görünüm → Ondalık Basamak menüsü açılır.
Her iki davranış da LivaDataGrid ile birebir aynıdır;
oradaki bölümlere bakın.
Aralık kuralı (Min / Max) — sağ tık menüsü
Sayısal ve ay (V001…V012) kolonlarında sağ tık menüsünün Denetim başlığı
altında Aralık Gir (Min / Max) yer alır: kolona alt/üst sınır konur, dışında
kalan hücreler kırmızı (ya da seçilirse yeşil) işaretlenir. Kural hiçbir hücreye
yazmaz, yalnızca görsel bir denetimdir. Kapsam olarak yalnız o kolon, tüm ay
kolonları ya da tüm sayı kolonları seçilebilir; uygulamadan önce kaç hücrenin
dışarıda kalacağı önizlenir.
Mantık ve pencere LivaDataGrid ile ortaktır — kapsam, renk ve önizleme ayrıntıları için LivaDataGrid sayfasındaki Aralık kuralı bölümüne bakın.
Başlık filtresinde arama
showHeaderFilter açtığınızda değer listesinin arama kutusuna bir mod seçici
(Contains / Begins with / Ends with) eklenir ve arama, ham sayı yerine
listede yazılı görünen metin üzerinde çalışır. Liste yeniden açıldığında
uygulanmış (işaretli) değerler en üstte listelenir. Otomatiktir, prop
gerektirmez; DataGrid ile aynı davranış — ayrıntı ve istisnalar için
LivaDataGrid sayfasındaki Başlık filtresinde arama
bölümüne bakın.
LivaTreeList'te Excel kipi (blok seçimi, hücre içi formül, doldurma tutamacı, seçim özeti) yok —excelModepropu yalnızcaLivaDataGrid'de bulunur. Ağaçta satır hiyerarşisi ve genişlet/daralt, dikdörtgen blok seçimiyle bağdaşmıyor.
Kolon tipi — LivaTreeListColumn
DataGrid kolonuyla aynı alanların çoğunu paylaşır (dataField, caption,
dataType, format yerine customizeText, width, visible, cellRender,
lookup, dropdown, fixed, fixedPosition, cellAlignment,
hidingPriority, summary, required). Ağaca özgü ek alan:
| Alan | Tip | Açıklama |
|---|---|---|
isCascade | boolean | Üst satırda düzenlenen değer tüm alt satırlara yayılır. Alt satırlarda karışık değer varsa üst hücre — gösterir. Varsayılan false. |
headerFilter | DevExtreme Column headerFilter alanı | Başlık filtresi listesini kendiniz tanımlar. Verilmezse Liva'nın biçimli metin üzerinde arayan varsayılanı uygulanır. |
dropdown alanı LivaTreeListColumnDropdown tipindedir ve DataGrid'deki
LivaDataGridColumnDropdown ile aynı alanları taşır
(dropDownWidth, searchEnabled ve arama modu seçicisi dahil). İki fark var:
size alanı yoktur — seçici her zaman 'xs' boyutunda çizilir — ve
remoteOperations boolean yerine { filtering?, sorting?, grouping?, paging? }
nesnesi de alabilir.
İçe/dışa aktarma
exportOptions (LivaTreeListExportOptions) enabled, actions
('excelAll' \| 'excelSelected' \| 'csv') ve fileName alanlarını alır —
DataGrid'den farkı, PDF dışa aktarmanın olmamasıdır. importExportSettings ise
DataGrid ile ortak LivaDataGridImportExportSettings tipini kullanır;
kurulum için Veri Alışverişi.
İçe aktarma başarıyla bittiğinde sihirbaz closeOnComplete'ten bağımsız olarak
hemen kapanır (DataGrid'de varsayılan, rapor adımında açık kalmaktır), ağaç
refresh() edilir ve
importExportSettings.onImportCompleted(report) çağrılır. refresh() yalnızca
bağlı veri kaynağını yeniden okur; yerel dizi veriyorsanız veriyi bu geri
çağrıda kendiniz yeniden yükleyin.
Adlandırılmış düzenler ve klavye seçimi
TreeList bir LivaGridStateProvider altında kullanıldığında Düzen menüsü
açılır. Bu durumda kolon yeniden boyutlandırma ve sıralama, ilgili proplar
açıkça kapatılmadıkça otomatik etkinleşir. Kolon sırası, genişliği, görünürlüğü,
sabitleme, sıralama ve filtreler saklanır; açık/kapalı düğümler, seçim ve arama
metni saklanmaz. id verilmezse kayıt anahtarı sayfa yolu, keyExpr ve kolon
alanlarından otomatik üretilir; aynı sayfada aynı kolonlu iki ağaç varsa ya da
kolon eklenip çıkarıldığında düzenlerin korunması gerekiyorsa sabit bir id
verin. Şema değişimlerinde stateVersion artırılmalıdır.
Kurulum ayrıntıları.
selectionMode="multiple" iken editör dışında basılan Ctrl+A (macOS'ta Cmd+A)
tüm satırları seçer. Giriş, metin alanı ve düzenlenen hücrelerde tarayıcının metin
seçme davranışı korunur.
Temel ve veri
| Prop | Tip | Varsayılan |
|---|---|---|
columns | LivaTreeListColumn[] | — (zorunlu) |
keyExpr | string | — (zorunlu) |
parentIdExpr | string | — (zorunlu) |
dataSource | Array<any> | LivaTreeListDataSourceTypes | — |
rootValue | any | — (kök satırlar için verilmeli, ör. 0) |
dataStructure | 'plain' | 'tree' | 'plain' |
hasItemsExpr | string | — (dalın çocuğu var mı) |
itemsExpr | string | — (dataStructure="tree" için çocuk alanı) |
autoExpandAll | boolean | false |
expandedRowKeys | any[] | — |
filterValue | any | — |
remoteOperations | { filtering?, sorting?, grouping?, paging? } | — |
title | string | — |
desc | string | — |
lang | string | — (uzak istekte Accept-Language başlığı) |
id | string | — (provider altında verilmezse anahtar otomatik üretilir) |
stateVersion | number | — |
Görünüm ve düzen
| Prop | Tip | Varsayılan |
|---|---|---|
height | number | string | '100%' |
width | number | string | '100%' |
visible | boolean | true |
fullHeight | boolean | false |
gridSize | 'xxs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'md' |
radius | 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'none' |
cursor | 'pointer' | 'default' | 'default' |
showBorders | boolean | true |
showRowLines | boolean | false |
showColumnLines | boolean | true |
showColumnHeaders | boolean | true |
rowAlternationEnabled | boolean | true |
hoverStateEnabled | boolean | true |
wordWrapEnabled | boolean | false |
columnAutoWidth | boolean | false |
columnHidingEnabled | boolean | false |
allowColumnResizing | boolean | düzen saklamada true, aksi halde false |
allowColumnReordering | boolean | düzen saklamada true, aksi halde false |
columnResizingMode | 'nextColumn' | 'widget' | 'widget' |
rtlEnabled | boolean | false |
noDataText | string | 'No data' |
showSkeleton | boolean | true |
isInitializing | boolean | false |
loadPanel | { enabled?, text?, showPane?, showIndicator?, shading? } | — (yükleme paneli her zaman kapalıdır) |
Kullanıcı erişilebilirlik tercihlerinde tablo yoğunluğu (gridDensity) ya da
zebra satırlar (zebraRows) için Otomatik dışında bir değer seçtiyse bu tercih
gridSize ve rowAlternationEnabled proplarını ezer (DataGrid ile aynı). TreeList
DevExtreme yükleme panelini kullanmaz; loadPanel verilse de panel kapalı kalır,
ilk yüklemede showSkeleton iskeleti görünür.
Seçim ve kaydırma
| Prop | Tip | Varsayılan |
|---|---|---|
selectionMode | 'none' | 'single' | 'multiple' | 'multiple' |
recursiveSelection | boolean | selectionMode === 'multiple' |
selectedRowKeys | any[] | — (seçim kontrollüdür) |
scrollingMode | 'standard' | 'virtual' | 'standard' |
showPager | boolean | false |
totalRow | boolean | false (ağacın altında Toplam kayıt şeridi) |
pagingDefaultPageSize | number | 10 |
pagingAllowedPageSizes | number[] | [5, 10, 20] |
Not:
selectionModevarsayılanı'multiple''dır; seçim istemiyorsanızselectionMode="none"verin. LivaDataGrid'den farklı olarakscrollingMode'standard'olduğu için sayfalayıcı ayarları burada etkilidir.
Seçim özeti (KPI pili)
| Prop | Tip | Varsayılan |
|---|---|---|
showSelectionSummary | boolean | false |
selectionSummarySelectedLabel | string | 'selected' |
selectionSummaryIcon | string | false | 'selectall' |
selectionSummaryTotalCount | number | — (kısmi yüklemede paydayı sabitler) |
renderSelectionSummary | (info: { selected, total }) => React.ReactNode | — |
Filtreleme ve arama
| Prop | Tip | Varsayılan |
|---|---|---|
showFilterRow | boolean | false |
showFilterOperationChooser | boolean | false |
showFilterSearchIcon | boolean | true |
showHeaderFilter | boolean | false |
showSearchPanel | boolean | false |
showCreateFilterButton | boolean | true |
Düzenleme (CRUD)
| Prop | Tip | Varsayılan |
|---|---|---|
editMode | 'cell' | 'row' | 'popup' | 'batch' | 'row' |
startEditAction | 'click' | 'dblClick' | 'click' |
allowAdding | boolean | false |
allowEditing | boolean | false |
allowDeleting | boolean | false |
startEditAction düzenlemenin tek tıkla mı çift tıkla mı başlayacağını belirler.
Ağaçta genişlet/daralt ve satır seçimi aynı tıklamayı paylaştığı için,
düzenlemenin yanlışlıkla açılmaması gereken tablolarda 'dblClick' verin.
Satır sürükleme
| Prop | Tip | Varsayılan |
|---|---|---|
enableRowDragging | boolean | false |
onRowDragging | (e: LivaRowDraggingEvent) => void | — |
orderExpr | string | — (kardeş sırası alanı, ör. "orderNo") |
draggingBatchField | string | — |
orderExpr verildiğinde aynı üst düğüm altındaki sürükle-bırak, etkilenen
kardeşlerin bu alanını yeniden yazar; satır anında yer değiştirir ve değişiklik
batch kaydında gönderilir.
Araç çubuğu ve dışa/içe aktarma
| Prop | Tip | Varsayılan |
|---|---|---|
showToolbar | boolean | true |
toolbarItems | any[] | — |
headerToolbar | React.ReactNode | — |
showColumnChooser | boolean | true |
isLivaContextMenu | boolean | true |
exportOptions | LivaTreeListExportOptions | — |
importExportSettings | LivaDataGridImportExportSettings | — |
monthOptions | MonthBuilderOptions | — |
Toplu işlemler
Yalnızca selectionMode="multiple" iken görünür. Davranış ve
LivaGridBulkAction alanları LivaDataGrid ile birebir aynıdır —
oradaki bölüme bakın.
| Prop | Tip | Varsayılan |
|---|---|---|
bulkActions | LivaGridBulkAction[] | — |
bulkSelectionTools | boolean | true |
allowBulkDelete | boolean | allowDeleting |
onBulkDelete | (e: LivaGridBulkActionContext) => void | Promise<void> | — |
Olay geri çağrıları
| Prop | Tip |
|---|---|
onRowClick | (e: RowClickEvent) => void |
onRowDblClick | (e: RowDblClickEvent) => void |
onCellClick | (e: CellClickEvent) => void |
onCellDblClick | (e: CellDblClickEvent) => void |
onSelectionChanged | (e: LivaTreeListSelectionChangedEvent) => void |
onExpandedRowKeysChanged | (expandedRowKeys: any[]) => void |
onRowPrepared | (e: RowPreparedEvent) => void |
onCellPrepared | (e: CellPreparedEvent) => void |
onRowInserted | (e: RowInsertedEvent) => void |
onRowUpdated | (e: RowUpdatedEvent) => void |
onRowRemoved | (e: RowRemovedEvent) => void |
onEditingStart | (e: EditingStartEvent) => void |
onInitNewRow | (e: any) => void |
onInitialized | (e: any) => void |
onSaving | (e: any) => void |
onToolbarPreparing | (e: any) => void |
onContextMenuPreparing | (e: ContextMenuPreparingEvent) => void |
onAddClick | (parentData?: any) => void |
onShowRowStatus | (rowData: any, rowKey?: any) => void |
onSelectionChanged, DevExtreme'in olayına ek olarak alt düğümleri de içeren
LivaTreeListSelectionChangedEvent tipini taşır. onContextMenuPreparing,
Liva'nın kendi sağ tık öğeleri hazırlandıktan sonra çağrılır; e.items'a
eklenen öğeler menüde görünür (örnek: LivaDataGrid).
Ref
LivaTreeList bir TreeListRef iletir (React.forwardRef); alttaki DevExtreme
TreeList örneğine ref.current.instance() ile erişilir.