# Tablolar ve Kayıt Listeleri

https://dev.wisecp.com/tr/tablolar-ve-kayit-listeleri

Tema kendi ızgara kütüphanesini getirmez: kayıt listeleri çekirdeğin Table bileşeniyle çalışır, gerisi düz markup'tır.

## Genel Bakış

Bir temanın ihtiyaç duyduğu her tabloyu iki yol karşılar. Soru kaç satır olduğu değil, **satırların ne olduğudur**.

- **Kayıt listesi**: Hizmetler, faturalar, alan adları, talepler, hesap hareketleri, mesajlar, etkinlik. Ziyaretçi arar, filtreler, sayfalar arasında gezer ve liste boş kalabilir. `Table` bileşenini `'renderer' => 'list'` ile kullanın.
- **Belge tablosu**: Fatura kalemleri, özellik karşılaştırması, DNS kayıtları, SMS raporu. Gezilmez, okunur ve sayfanın parçasıdır. Şablona düz markup yazın.

## Ön Koşullar

- Temanız etkin olmalı, böylece `Theme::active()` onun dizinini verir.
- Bileşenin kendisini biliyor olmanız gerekir; bu makale yalnız müşteri tarafındaki görünümü anlatır.
- Tema kökünüzde bir `tables/` dizini bulunmalı.

## Yapı

Dört katman var ve her biri ayrı bir dosyaya ait. Yukarıdaki sayfalar için çekirdek denetleyici zaten hazırdır, yani tema genelde yalnız ikinci ve üçüncü katmanı yazar.

- **Veri ve sayfalama**: Çekirdek denetleyici. Tabloyu kurar ve iki model closure'ını verir.
- **Satır markup'ı**: Sizin preset'iniz: `templates/website/{Tema}/tables/{ad}.php`.
- **Kap, araç şeridi, sayfalayıcı**: Sizin view'ınız: `views/account/{ad}.tpl`.
- **Etkileşim**: Sizin `list.js` dosyanız: istemci araması, filtre, sayfalama, sayaç metni, boş durum.

## Adım Adım

### Kayıt listesi ekleme

1. Sayfanın preset'ini başka bir temadan kendi `tables/` dizininize kopyalayın. Dosya adı, denetleyicinin verdiği tablo adıyla aynıdır.
2. `setRowRender()` içindeki markup'ı kendi tasarım dilinizle yeniden yazın; veriye ve sıraya dokunmayın.
3. Aynı markup'ı view'ın `{foreach}` dalına da uygulayın, böylece ilk sayfa ile sonraki sayfalar aynı görünür.
4. Kaba üç metin köprüsünü verin, sonra sayfayı açıp sayfalar arasında gezin. Sayaç artık sizin dilinizde okunur ve bir filtre hiçbir kaydı bulamadığında boş durum görünür.

## Referans

Liste görünümü bileşenin üç davranışını değiştirir.

- **Table::preset()**: İki ayrı kökten okur. Panelde `templates/admin/tables/`, sitede `Theme::active()->dir()."tables"`. Admin dizinine konan bir preset hiçbir zaman bulunamaz.
- **setRowRender(callable)**: Callback'iniz satırın tamamını `$row["html"]` içinde döndürür. `$row["data"]` altındaki kolon matrisi bu görünümde kullanılmaz.
- **buildList(string $format = ''): string**: Satırları birleştirip döndürür. Kolon yok, dilimleme yok ve `justBody` tam çağrıyla aynı sonucu verir.
- **Sıralama**: Tıklanacak kolon başlığı olmadığı için sıra, modelin izin listesinden gelir.
- **İndirme**: Burada hiç sunulmaz. Yetki kontrolü müşteri oturumunda olumsuz döner.

Şablonun yapamadığı işi denetleyici bitirir, çünkü tema şablonu korumalı alanda bileşeni çağıramaz:

- **build('justBody')**: Satırları önceden üretir ve view'a hazır bir dize olarak verir.
- **getAjax()**: Veri adresidir ve **yalnız** hesap satır eşiğini aştığında dolar. View bunu kaba `data-ajax` olarak yazar.
- **ajaxControl(['baseLink' => …])**: Veri isteğini yanıtlar ve yanıtladıysa boş olmayan bir dize döndürür; denetleyici o değeri olduğu gibi geri verir.

> **Küçük hesaplar sunucuya hiç gitmez**
> 
> Eşiğin altında bütün satırlar ilk yanıtta gelir, `data-ajax` bulunmaz ve arama, filtre, sayfalama tarayıcıda olur. Eşiğin üstünde aynı adres tek seferde bir sayfa verir. Markup'ınız ikisinde de aynıdır; aşağıdaki satır öznitelikleri bu yüzden kendi değerlerini taşır.

Kap, etkileşim betiğinin ihtiyaç duyduğu metinleri taşır:

- **data-noun**: Betiğin içindeki anahtar, İngilizcedir ve hiç gösterilmez.
- **data-txt-count · data-txt-nores · data-txt-noun**: Çevrilmiş sayaç cümlesi, eşleşme yok cümlesi ve kaydın adı. Birini yazmazsanız o metin İngilizceye düşer.

## Örnek

```php
/** @var \WISECP\Components\Table $table */
if (!isset($table)) return;

$table->setRowRender(function ($row) {
    $service = $row["model"];
    $name    = htmlspecialchars($service["name"]);
    $status  = $service["status"];
    $danger  = in_array($status, ['suspended', 'expired'], true) ? ' is-danger' : '';
    $link    = LinkGenerator::client("service-detail", [$service["id"]]);

    // Satırın tamamı, kendi markup'ınızla. Hiçbir yerde <td> yok.
    $row["html"] = '<article class="list-item' . $danger . '">'
        . '<a href="' . $link . '">' . $name . '</a>'
        . '<span class="badge">' . $status . '</span>'
        . '</article>';

    return $row;
});
```

```html
<div class="list-rows" data-noun="services"
     data-txt-count="{lang key='website/index/list-count'}"
     data-txt-nores="{lang key='website/index/list-nores'}"
     data-txt-noun="{lang key='website/services/noun'}">
    {$rows nofilter}
</div>
```

## Tuzaklar

> **Yanlış dizindeki preset sessizce başarısız olur**
> 
> Arama dosyanın var olup olmadığını sorar ve yoksa devam eder. Hiçbir kayıt tutulmaz, hata görünmez, liste yalnızca boş gelir. Satırlarınız eksikse kodunuzdan önce yolu kontrol edin.

> **İlk sayfa ile sonraki sayfalar eşleşmeli**
> 
> View birinci sayfayı, preset ondan sonraki her sayfayı üretir. İkisi ayrışırsa ziyaretçi ileri gittiği anda satırlar şekil değiştirir.

> **Bir değil iki boş durum**
> 
> Hiç kayıt yoksa araç şeridi, liste ve sayfalayıcı birlikte yerini boş duruma bırakır ve ilk kaydı oluşturma yolu sunulabilir. Filtre hiçbir kaydı bulamadığındaysa boş durum kabın içinde kalır ve filtreyi temizleme yolu sunar. Yalnız birini yazmak ziyaretçiyi çıkmazda bırakır.

> **Dosya her temada gerekir**
> 
> Preset'ler temanın içinde yaşar, yani her tema yedi dosyanın kendi kopyasını taşır. Eksik kalan biri o temaya boş bir listeye mal olur.

## İlgili Makaleler

- [Arayüz Bileşenleri](https://dev.wisecp.com/tr/arayuz-bilesenleri)
- [Müşteri Paneli](https://dev.wisecp.com/tr/musteri-paneli)
