1386 lines
93 KiB
Markdown
1386 lines
93 KiB
Markdown
# Low-Code Genişletilmiş Referans (JSON Kolon ve Modül Sözleşmeleri)
|
||
|
||
`lowcode.instructions.md` **nasıl üretileceğini** anlatır; bu dosya **neyin ayarlanabildiğini**
|
||
tek tek listeler. Orada "bunun bir JSON kolonu var" denen her şeyin alan alan karşılığı burada
|
||
durur: ListForm/ListFormField'ın tüm JSON kolonları, grafik sözleşmesi, Visual Designer envanteri
|
||
ve zamanlanmış e-posta modülü. Son bölüm (§12) Saas ve Administration menülerindeki **hazır
|
||
gelen bütün ekranları** ve bunların yeni bir komponentte nasıl kullanılacağını listeler.
|
||
|
||
**Kullanım sırası:** `ai.instructions.md` → `lowcode.instructions.md` → **bu dosya** → `README.md`.
|
||
Bir istek geldiğinde önce ana dosyadaki karar sırasını işlet; "hangi anahtarı yazacağım?"
|
||
sorusunda buraya bak.
|
||
|
||
**Kaynak:** Buradaki her tablo `api/src/Sozsoft.Platform.Application.Contracts/ListForms/**` ve
|
||
`api/src/Sozsoft.Platform.Domain/Entities/Tenant/ListForm/ListForm.cs` dosyalarından çıkarılmıştır.
|
||
Çelişki hâlinde **kod esastır**; bu dosya güncellenir.
|
||
|
||
**Ortak kurallar**
|
||
|
||
- Bütün `*Json` kolonları veritabanında **tek satır JSON string** olarak durur. Wizard seed
|
||
dosyasının `ListForm`/`Fields` bölümleri ekranın DTO sözleşmesini taşıdığı için orada bu
|
||
kolonlar kaçışlanmış metin değil, tipli karşılıkları (`SchedulerOptionJson` →
|
||
`SchedulerOptionDto`) olarak yer alır; kaçışlama yalnızca `EditorOptions`, `EditorScript`,
|
||
`LookupQuery` gibi gerçekten metin olan alanlar içindir.
|
||
- Varsayılan değeri olan bir alanı tekrar yazmak zorunda değilsin; yalnızca farklı olanı yaz.
|
||
- `Accepted Values` yazan yerlerde değer birebir eşleşmelidir (büyük/küçük harf dahil).
|
||
- **Bilinmeyen anahtar sessizce düşer — tarayıcıya hiç ulaşmaz.** `GridOptionsDto` bu 47
|
||
kolonun ham metnini `[JsonIgnore]` ile gizler ve istemciye yalnızca tipli DTO'ya
|
||
(`SchedulerOptionJson` → `SchedulerOptionDto`) çözülmüş hâlini yollar. Dolayısıyla:
|
||
- DTO'da olmayan bir DevExtreme seçeneğini `*Json`'a yazmak **işe yaramaz**; kalıcı olarak
|
||
gerekiyorsa önce ilgili DTO'ya alan eklenir (ve bu dosya güncellenir).
|
||
- Yanlış **tipte** yazılan değer (`"3"` yerine `3`, dizi yerine metin) `JsonSerializer`
|
||
tarafında `JsonException` fırlatır ve ekranın metadata isteği tamamen düşer — sessiz
|
||
değil, gürültülü bir hatadır. Tipleri tablodaki gibi yaz.
|
||
- Bu kural yalnızca alan seviyesindeki `ListFormField.EditorOptions` için geçmez: orası
|
||
ham metin olarak taşınır, tanımadığı anahtarı doğrudan editöre geçirir (§9.8).
|
||
|
||
---
|
||
|
||
## 0. Üretim yetenek envanteri — bir komponent üretirken tara
|
||
|
||
Bir ekran/komponent üretirken **her katmanı sırayla geç**. Cevabı "gerekmiyor" olan katmanı atla,
|
||
ama hiçbirini görmeden bırakma; kullanıcı "şunu da yapabilir miydik?" dediğinde cevap
|
||
"kod yazmamız gerekir" olmasın.
|
||
|
||
| # | Katman | Sorulacak soru | Nerede |
|
||
| --- | --- | --- | --- |
|
||
| 0 | **Hazır yetenek** | Bu talebin karşılığı Saas/Administration menüsünde zaten var mı? | §12.5 |
|
||
| 1 | **Veri** | Tablo/view var mı, join gerekiyor mu, anahtar ve tipi ne? | `lowcode` §8 · §9.6 |
|
||
| 2 | **Ekran türü** | Liste mi, tek kayıt formu mu, serbest yerleşim mi? Kaç görünüm açılacak? | `lowcode` §0.6.1 · §9.8 · §5.4 |
|
||
| 3 | **Sütunlar** | Editör tipi, biçim, hizalama, genişlik, band, gizli/aktif | `lowcode` §4.3 · §9.7 |
|
||
| 4 | **Lookup** | Sabit liste mi, sorgu mu, servis mi? Cascade var mı? | `lowcode` §4.3.4 |
|
||
| 5 | **Varsayılanlar** | Kullanıcı/tarih/tenant/sequence/sorgu ile otomatik dolacak alanlar | `lowcode` §4.3.5 · §9.9 |
|
||
| 6 | **Alan davranışı** | Hesap, kopyalama, temizleme, koşullu kilit, uyarı, servis çağrısı | `lowcode` §5 |
|
||
| 7 | **Editör görünümü** | Maske, ondalık, tarih biçimi, arama, çoklu seçim, görsel yükleme | `lowcode` §6 |
|
||
| 8 | **Doğrulama** | Zorunluluk, aralık, desen, karşılaştırma + sunucu tarafı kontrol | `lowcode` §4.3.6 · §4 |
|
||
| 9 | **Filtre/arama** | Filtre satırı, başlık filtresi, arama paneli, ek filtre çubuğu, grup paneli | §2.6 · `lowcode` §4.3.8 |
|
||
| 10 | **Özet** | Toplam/adet satırı, grup özetleri, pivot | §9.5 · §6 |
|
||
| 11 | **Biçimlendirme** | Koşullu satır/hücre rengi, CSS sınıfı | `lowcode` §4.3.7 |
|
||
| 12 | **Düzenleme deneyimi** | Popup/satır/hücre/batch, form grupları, kopyalama, toplu silme | §3 |
|
||
| 13 | **Aksiyonlar** | Toolbar ve satır butonları: adres, diyalog, script, yetki, koşullu görünürlük | `lowcode` §4.9 |
|
||
| 14 | **Yazma mantığı** | Özel SQL, before/after kancaları, farklı servis adresi | §4 |
|
||
| 15 | **Ana-detay** | Alt form sekmeleri ve ilişki alanları | §5.2 |
|
||
| 16 | **Gösterge** | Üstte KPI kartları, grafik | §5.3 · §8 |
|
||
| 17 | **Süreç** | Onay akışı, bilgilendirme, durum alanları | `lowcode` §4.7 |
|
||
| 18 | **Otomasyon** | Zamanlanmış iş, zamanlanmış e-posta, bildirim kuralı | `lowcode` §9.10–§9.11 · §11 |
|
||
| 19 | **Çıktı** | Hazır grid raporu ya da rapor şablonu | `lowcode` §9.12 |
|
||
| 20 | **Yetki** | Ekran, alan, komut ve buton yetkileri; menü görünürlüğü | §5.1 · `lowcode` §4.2 |
|
||
| 21 | **Tenant/şube** | `IsTenant`, `IsBranch`, `IsOrganizationUnit`, sorgularda kırılım | `lowcode` §4.2 |
|
||
| 22 | **Dil** | Menü, başlık, alan, buton, mesaj metinleri EN + TR | `lowcode` §4.2 |
|
||
| 23 | **Kullanıcı tercihi** | Grid durumunun saklanması, kullanıcı/rol/dil varyantı | §2.5 · §5.7 |
|
||
| 24 | **Seed** | Üretilen her artefaktın dosyası + yalnızca DB'de yaşayan kayıtların geri getirici script'i | `lowcode` §0.2 · §9.14 |
|
||
|
||
Serbest yerleşimli bir komponent (Visual Designer) üretiyorsan 0–2 ve 13–24 aynen geçerlidir;
|
||
3–12 yerine tasarımcı envanteri (§10.1), `Form` sözleşmesi (§10.2), veri kaynağı/filtre
|
||
sözleşmesi (§10.4), bileşen prop sözleşmeleri (§10.5–§10.9), olay yükleri (§10.10) ve event
|
||
script'leri (`lowcode` §7.8) kullanılır. 20. katman (yetki) orada
|
||
iki yerdedir: düğüm başına `designerPermission` ve `Form`'un dört komut yetkisi.
|
||
|
||
Katmanların çoğunda cevap yeni bir artefakt değil, platformun **hazır bir ekranıdır**: numaratör,
|
||
bildirim, zamanlanmış iş, rapor, ayar, dil, yetki, şube, kısıt, dosya. Hepsinin envanteri §12'de —
|
||
"kod yazmamız gerekir" demeden önce §12.5'e bak.
|
||
|
||
---
|
||
|
||
## 1. ListForm JSON kolon haritası
|
||
|
||
Bir List ekranının bütün davranışı bu kolonlardadır. "Şunu yapabilir miyiz?" sorusunun cevabı
|
||
önce bu tabloda aranır.
|
||
|
||
Aşağıdaki tablo `*Json` bloklarını listeler. Bunların **öncesinde** ekranın düz kolonları gelir
|
||
ve çoğu isteğin cevabı aslında oradadır:
|
||
|
||
| Kolon | Varsayılan | Ne yapar |
|
||
| --- | --- | --- |
|
||
| `ListFormCode` | — | Ekranın kimliği; route, metadata ve varyantlar bu koda bağlanır |
|
||
| `DataSourceCode` | `"Default"` | Hangi bağlantıdan okunacağı (`Sas_H_DataSource`) |
|
||
| `SelectCommandType` | `1` Table | `1` Table · `2` View · `3` TableValuedFunction · `4` Query · `5` StoredProcedure |
|
||
| `SelectCommand` | — | Tablo/view adı, fonksiyon çağrısı ya da sorgu metni |
|
||
| `TableName` | `SelectCommand` | Üretilen `SELECT`'te kolonların ve join'lerin önüne yazılan **alias**. Boşsa `SelectCommand` kullanılır; `SelectCommand` bir sorgu metni ya da fonksiyon çağrısıysa buraya kısa bir ad yaz |
|
||
| `KeyFieldName` · `KeyFieldDbSourceType` | — · `16` String | Anahtar kolon ve `System.Data.DbType` karşılığı |
|
||
| `SelectFieldsDefaultValueJson` | — | **Okuma** sorgusuna parametre olarak katılan değerler (`FieldsDefaultValueDto[]`) — `@USERID`, `@TENANTID` gibi |
|
||
| `DefaultFilter` | — | Her sorgunun sonuna `AND` ile eklenen sabit `WHERE` koşulu. `DefaultValueHelper` üzerinden geçer, yani `@USERID`/`@TENANTID`/`@NOW` gibi token'lar çözülür. Soft delete'li tabloda (`IsDeletedField: true`) wizard buraya `"IsDeleted" = 'false'` yazar |
|
||
| `SortMode` | — | `UiGridSortModeEnum`: `1` Single · `2` Multiple · `3` None |
|
||
| `PageSize` | — | Sayfa başına kayıt; `0` = tümü |
|
||
| `Name` · `Title` · `Description` | — | Ekran adı, başlığı, açıklaması — **dil anahtarı** yazılır |
|
||
| `IsTenant` · `IsBranch` · `IsOrganizationUnit` | `IsMultiTenant` · `false` · `false` | Otomatik kırılım filtresi |
|
||
|
||
| Kolon | Ne yapılandırır | Bölüm |
|
||
| --- | --- | --- |
|
||
| `ColumnOptionJson` | Grid genel görünümü (kenarlık, satır rengi, kolon seçici, sabitleme) | §2.1 |
|
||
| `CommandColumnJson` | Toolbar ve satır butonları | `lowcode` §4.9 |
|
||
| `RowJson` | Satır yüksekliği ve metin kaydırma | §2.2 |
|
||
| `PagerOptionJson` | Sayfalama şeridi | §2.3 |
|
||
| `SelectionJson` | Seçim modu ve checkbox davranışı | §2.4 |
|
||
| `StateStoringJson` | Kullanıcının grid tercihlerinin saklanması | §2.5 |
|
||
| `FilterRowJson` · `HeaderFilterJson` · `FilterPanelJson` · `SearchPanelJson` · `GroupPanelJson` | Filtre/arama/gruplama panelleri | §2.6 |
|
||
| `ExtraFilterJson` | Ekran üstü ek filtre çubuğu | `lowcode` §4.3.8 |
|
||
| `EditingOptionJson` | Düzenleme modu, izinler, popup ayarları | §3.1 |
|
||
| `EditingFormJson` | Düzenleme formunun grup/sekme yerleşimi | §3.2 |
|
||
| `InsertCommand` · `UpdateCommand` · `DeleteCommand` (+ `*Before`/`*After`) | Özel SQL komutları ve kancalar | §4 |
|
||
| `*FieldsDefaultValueJson` | Otomatik doldurulan alanlar | `lowcode` §4.3.5 |
|
||
| `*ServiceAddress` | Yazma işlemini karşılayan uç | §4.3 |
|
||
| `PermissionJson` | Ekran yetkileri | §5.1 |
|
||
| `SubFormsJson` | Alt form sekmeleri | §5.2 |
|
||
| `WidgetsJson` | KPI kartları | §5.3 |
|
||
| `WorkflowJson` | Onay akışı | `lowcode` §4.7 |
|
||
| `LayoutJson` | Açık görünümler ve varsayılan | §5.4 |
|
||
| `PivotOptionJson` | Pivot görünümü | §6 |
|
||
| `TreeOptionJson` · `GanttOptionJson` · `SchedulerOptionJson` · `TodoOptionJson` | Ağaç/Gantt/Takvim/Kanban eşlemeleri | §7 |
|
||
| `SeriesJson` ve diğer 21 grafik kolonu | Chart görünümü | §8 |
|
||
| `CustomJsSourcesJson` · `CustomStyleSourcesJson` | Sayfaya enjekte edilen JS/CSS | §5.5 |
|
||
| `AdaptiveLayoutJson` | Dar ekranda öğe gizleme (grafik) | §8.4 |
|
||
| `CommonJson` · `DataSourceJson` | Grafik geneli ve grafik sorgusu | §8.2 · §8.3 |
|
||
| `Width` · `Height` · `FullHeight` | Ekran boyutu | — |
|
||
| `ListFormType` · `IsSubForm` · `SubFormsListFormType` · `ShowNote` | Ekranın türü ve alt form davranışı | §5.6 |
|
||
| `CultureName` · `UserId` · `RoleId` | Aynı ekranın dil/kullanıcı/rol varyantı | §5.7 |
|
||
|
||
---
|
||
|
||
## 2. Grid görünümü
|
||
|
||
### 2.1 `ColumnOptionJson` (`GridColumnOptionDto`)
|
||
|
||
| Anahtar | Varsayılan | Anlam |
|
||
| --- | --- | --- |
|
||
| `ShowBorders` | `true` | Dış kenarlık |
|
||
| `ShowRowLines` | `true` | Satır çizgileri |
|
||
| `ShowColumnLines` | `false` | Kolon çizgileri |
|
||
| `RowAlternationEnabled` | `true` | Tek/çift satır renklendirme |
|
||
| `AllowColumnReordering` | `true` | Kullanıcı kolon sırasını değiştirebilir |
|
||
| `AllowColumnResizing` | `true` | Kolon genişliği değiştirilebilir |
|
||
| `ColumnResizingMode` | `"widget"` | `nextColumn` \| `widget` |
|
||
| `ColumnAutoWidth` | `false` | İçeriğe göre genişlik |
|
||
| `ColumnFixingEnabled` | `false` | Kolon sabitleme menüsü |
|
||
| `ColumnChooserEnabled` | `false` | Kolon seçici düğmesi |
|
||
| `ColumnChooserMode` | `"dragAndDrop"` | `dragAndDrop` \| `select` |
|
||
| `ColumnHidingEnabled` | `true` | Dar ekranda kolon gizleme |
|
||
| `HoverStateEnabled` | `false` | Satır üzerine gelince vurgulama |
|
||
| `FocusedRowEnabled` | `true` | Odaklı satır |
|
||
| `ShowColumnHeaders` | `true` | Başlık satırı |
|
||
| `RtlEnabled` | `false` | Sağdan sola |
|
||
|
||
### 2.2 `RowJson` (`GridRowDto`)
|
||
|
||
| Anahtar | Varsayılan | Anlam |
|
||
| --- | --- | --- |
|
||
| `RowHeight` | `"auto"` | Satır yüksekliği (CSS) |
|
||
| `WhiteSpace` | `"normal"` | Uzun metnin kaydırılması |
|
||
| `OverflowWrap` | `"break-word"` | Kelime kırma |
|
||
|
||
### 2.3 `PagerOptionJson` (`GridPagerOptionDto`)
|
||
|
||
Adı yalnızca sayfalamayı çağrıştırsa da bu blok **kaydırma ve yükleniyor panelini** de taşır.
|
||
|
||
| Anahtar | Varsayılan | Anlam |
|
||
| --- | --- | --- |
|
||
| `Visible` | `true` | Sayfalama şeridi |
|
||
| `ShowPageSizeSelector` | `false` | Sayfa boyu seçici |
|
||
| `ShowInfo` | `false` | "Page 1 of 4 (37 items)" bilgisi |
|
||
| `ShowNavigationButtons` | `true` | İleri/geri düğmeleri |
|
||
| `AllowedPageSizes` | `"10,20,50,100"` | **Virgüllü metin**, dizi değil |
|
||
| `InfoText` | `"Page {0} of {1} ({2} items)"` | `{0}` sayfa · `{1}` toplam sayfa · `{2}` kayıt |
|
||
| `DisplayMode` | `"adaptive"` | `adaptive` \| `compact` \| `full` |
|
||
| `ScrollingMode` | `"standard"` | `standard` \| `virtual` \| `infinite` — uzun listelerde `virtual` |
|
||
| `LoadPanelEnabled` | `"auto"` | **Metin** alanıdır: `"auto"` \| `"true"` \| `"false"` |
|
||
| `LoadPanelText` | `"Loading..."` | Yükleniyor metni |
|
||
|
||
Sayfa başına kayıt sayısı ekranın `PageSize` alanındadır; `0` = tümü. `ScrollingMode` ile
|
||
`PageSize` birlikte düşünülür: `virtual`/`infinite` seçilip `PageSize: 0` yazılırsa sayfalama
|
||
devre dışı kalır ve tüm küme tek istekte çekilir.
|
||
|
||
### 2.4 `SelectionJson` (`SelectionDto`)
|
||
|
||
| Anahtar | Varsayılan | Değerler |
|
||
| --- | --- | --- |
|
||
| `Mode` | `"none"` | `single` \| `multiple` \| `none` |
|
||
| `AllowSelectAll` | `false` | |
|
||
| `SelectAllMode` | `"allPages"` | `allPages` \| `page` |
|
||
| `ShowCheckBoxesMode` | `"always"` | `always` \| `none` \| `onClick` \| `onLongTap` |
|
||
|
||
Toolbar butonları seçili satırlarla çalışır (`lowcode` §4.9); onay akışı varsa wizard `single` yazar.
|
||
|
||
### 2.5 `StateStoringJson` (`StateStoringDto`)
|
||
|
||
| Anahtar | Varsayılan | Anlam |
|
||
| --- | --- | --- |
|
||
| `Enabled` | `true` | Kullanıcının kolon/filtre/sıralama tercihleri saklansın mı |
|
||
| `Type` | `"custom"` | `custom` (sunucuda kullanıcı bazlı) \| `localStorage` \| `sessionStorage` |
|
||
| `StorageKey` | — | Anahtar; boşsa ekran kodundan türer |
|
||
| `SavingTimeout` | `5000` | Değişiklikten kaç ms sonra yazılacağı — **`[Range(1500, 5000)]`**, dışına çıkan değer doğrulamada reddedilir |
|
||
|
||
`Type: "custom"` tercih edilir: tercih sunucuda `ListFormCustomization` kaydı olarak
|
||
(`ListFormCustomizationTypeEnum.GridState = 2`) kullanıcı bazlı saklanır, bu yüzden başka
|
||
tarayıcıdan girildiğinde de korunur. `localStorage`/`sessionStorage` yalnızca o tarayıcıdadır.
|
||
|
||
### 2.6 Filtre, arama ve gruplama panelleri
|
||
|
||
**`FilterRowJson`** (`GridFilterRowDto`): `Visible` (`false`), `ApplyFilter` (`auto` \| `onClick`),
|
||
`AllowUserUiFilterSave` (varsayılan `true` — kullanıcı kendi filtresini kaydedebilir;
|
||
kayıt `ListFormCustomizationTypeEnum.UserUiFilter = 1` olarak tutulur).
|
||
|
||
**`HeaderFilterJson`** (`GridHeaderFilterDto`): `Visible` (`false`), `AllowSearch` (`false`),
|
||
`Height` (`325`), `Width` (`252`), `SearchTimeout` (`500`).
|
||
|
||
**`FilterPanelJson`** (`FilterPanelDto`): `Visible` (`false`), `FilterEnabled` (`false`),
|
||
`Texts.ClearFilter` (`"Clear"`) / `Texts.CreateFilter` (`"Create Filter"`) /
|
||
`Texts.FilterEnabledHint` (`"Enable the filter"`), `CustomizeText` (serbest JSON; filtre
|
||
metnini biçimlendirmek için — sözlükte tipi yoktur, olduğu gibi bileşene geçer).
|
||
|
||
**`SearchPanelJson`** (`SearchPanelDto`): `Visible` (`false`), `Width` (`160`).
|
||
|
||
**`GroupPanelJson`** (`GroupPanelDto`): `Visible` (`false`), `AutoExpandAll` (`false`).
|
||
`AutoExpandAll: true` **fazladan bir sorgu daha** çalıştırır.
|
||
|
||
---
|
||
|
||
## 3. Düzenleme
|
||
|
||
### 3.1 `EditingOptionJson` (`GridEditingDto`)
|
||
|
||
| Anahtar | Varsayılan | Anlam |
|
||
| --- | --- | --- |
|
||
| `Mode` | `"popup"` | `batch` \| `cell` \| `row` \| `form` \| `popup` |
|
||
| `RefreshMode` | `"full"` | `full` \| `reshape` \| `repaint` |
|
||
| `AllowAdding` / `AllowUpdating` / `AllowDeleting` | `false` | Aksiyon izinleri (yetki ayrıca `PermissionJson`) |
|
||
| `AllowAllDeleting` | `false` | Toplu silme düğmesi |
|
||
| `AllowDuplicate` | `false` | Kaydı kopyalayarak yeni kayıt |
|
||
| `AllowDetail` | `false` | Satırda Detay düğmesi |
|
||
| `ConfirmDelete` | `true` | Silme onayı |
|
||
| `UseIcons` | `false` | Aksiyonlar ikon olarak |
|
||
| `NewRowPosition` | `"viewportTop"` | `first` \| `last` \| `pageTop` \| `pageBottom` \| `viewportTop` \| `viewportBottom` |
|
||
| `StartEditAction` | `"click"` | `click` \| `dblClick` |
|
||
| `SelectTextOnEditStart` | `false` | Düzenlemeye girince metni seç |
|
||
| `EditColumnName` | — | Aksiyon sütununun başlığı |
|
||
| `SendOnlyChangedFormValuesUpdate` | `false` | Update'te yalnızca değişen alanları gönder |
|
||
| `AddPageUrl` | — | Yeni kayıt popup yerine bu adreste açılır |
|
||
| `Popup` | — | Aşağıdaki alt nesne |
|
||
|
||
`Popup` (`GridEditingPopupDto`): `Title`, `ShowTitle` (`true`), `Width` (`700`), `Height` (`500`),
|
||
`FullScreen` (`false`), `HideOnOutsideClick` (`true`), `ResizeEnabled` (`true`),
|
||
`DragEnabled` (`true`), `RestorePosition` (`true`),
|
||
`Position` (`center` \| `top` \| `bottom` \| `left` \| `right`).
|
||
|
||
### 3.2 `EditingFormJson` (`EditingFormDto[]`)
|
||
|
||
Düzenleme formundaki grupların listesi. Alanların hangi gruba düştüğü `ListFormField` üzerindeki
|
||
`EditGroupOrderNo` / `EditOrderNo` ile belirlenir.
|
||
|
||
| Anahtar | Varsayılan | Anlam |
|
||
| --- | --- | --- |
|
||
| `Order` | `1` | Grubun sırası (`EditGroupOrderNo` ile eşleşir) |
|
||
| `ItemType` | `"group"` | `group` (kullanılan) \| `tabbed` \| `simple` \| `empty` \| `button` |
|
||
| `Caption` | — | Grup başlığı (dil anahtarı) |
|
||
| `ColCount` | `2` | Grup içi kolon sayısı |
|
||
| `ColSpan` | `2` | Grubun formda kapladığı kolon |
|
||
|
||
Wizard bu listeyi `Groups` bloğundan üretir; anahtar alan ve `IncludeInEditingForm: false`
|
||
olanlar dışarıda kalır.
|
||
|
||
---
|
||
|
||
## 4. Yazma komutları ve kancalar
|
||
|
||
### 4.1 Komutlar
|
||
|
||
| Kolon | Ne zaman |
|
||
| --- | --- |
|
||
| `InsertCommand` / `UpdateCommand` / `DeleteCommand` | Boşsa platform komutu kendi üretir; doluysa **bu SQL** çalışır |
|
||
| `InsertBeforeCommand` / `InsertAfterCommand` | Insert'ten önce/sonra |
|
||
| `UpdateBeforeCommand` / `UpdateAfterCommand` | Update'ten önce/sonra |
|
||
| `DeleteBeforeCommand` / `DeleteAfterCommand` | Delete'ten önce/sonra |
|
||
|
||
**Kancalar, kod yazmadan iş mantığı çalıştırmanın yeridir**: stok düşme, hareket kaydı, durum
|
||
güncelleme, log, bildirim kuyruğuna satır ekleme. Karmaşıklaşınca gövdeyi bir stored procedure'e
|
||
taşı ve kancadan onu çağır (`EXEC Wms_S_AfterOrderInsert @Id, @USERID`).
|
||
|
||
### 4.2 Komut içinde kullanılabilen anahtarlar
|
||
|
||
| Token | Değer |
|
||
| --- | --- |
|
||
| `@ID` | Kaydın anahtarı (Delete'te seçili anahtar kümesi) |
|
||
| `@USERID` · `@USERNAME` · `@ROLES` | Oturumdaki kullanıcı |
|
||
| `@FieldName` | Ekrandan gelen o alanın değeri — tablodaki her kolon için geçerlidir (`@OrderNo`, `@Amount`) |
|
||
|
||
`*FieldsDefaultValueJson` ile üretilen değerler (`@NOW`, `@NEWID`, `@TENANTID`, Sequence…)
|
||
komuta parametre olarak katılır (`lowcode` §4.3.5). **String birleştirme ile sorgu kurma.**
|
||
|
||
### 4.3 `*ServiceAddress`
|
||
|
||
`InsertServiceAddress` / `UpdateServiceAddress` / `DeleteServiceAddress` varsayılan olarak
|
||
`list-form-data/insert|update|delete` uçlarıdır. Yazma işini bir Custom Endpoint ya da Dynamic
|
||
Service'e devretmek istiyorsan bu alanı o ucun adresiyle değiştirirsin — ekranın geri kalanı
|
||
(form, doğrulama, yetki) aynı kalır.
|
||
|
||
**Çok değerli alanlar bu iki yolda farklı davranır.** Varsayılan uçta payload bir sözlüktür
|
||
(`data: {...}`) ve `dxTagBox` dizisini `QueryHelper.GetFormattedValue` `|` ile birleştirir.
|
||
Tipli bir DTO alan uçta (`list-form-dynamic-api/...` gibi) böyle bir adım yoktur: dizi `string`
|
||
property'ye bağlanamaz ve istek `400` ile düşer. Çözüm, DTO alanına
|
||
`[JsonConverter(typeof(MultiValueStringJsonConverter))]` eklemektir — `Modules` alanında
|
||
uygulanmış örneği `CreateUpdateTenantInput` / `CreateTenantFromOrderInput` taşır. Yalnızca
|
||
**girdi** DTO'larına eklenir; okuma DTO'larında (`SettingDefinitionDto.Providers`,
|
||
`PlatformPermissionGrantInfoDto.Modules`) karşılığı yoktur çünkü o ekranlar varsayılan SQL
|
||
yolundan kaydeder.
|
||
|
||
---
|
||
|
||
## 5. Ekran seviyesindeki diğer bloklar
|
||
|
||
### 5.1 `PermissionJson` (`PermissionCrudDto`)
|
||
|
||
Tek harfli anahtarlar: `R` (read), `C` (create), `U` (update), `D` (delete), `E` (export),
|
||
`I` (import), `N` (note). Değerler **yetki adıdır**, boolean değil:
|
||
|
||
```json
|
||
{ "R": "App.Mrp.Orders", "C": "App.Mrp.Orders.Create", "U": "App.Mrp.Orders.Update",
|
||
"D": "App.Mrp.Orders.Delete", "E": "App.Mrp.Orders.Export", "I": "App.Mrp.Orders.Import",
|
||
"N": "App.Mrp.Orders.Note" }
|
||
```
|
||
|
||
Alan seviyesindeki karşılığı `ListFormField.PermissionJson`'dır ve **şeması farklıdır**
|
||
(`ListFormFieldPermissionDto`) — ekran seviyesindeki yedi harfli sözleşmeyi buraya kopyalama:
|
||
|
||
| Anahtar | Tip | Anlam |
|
||
| --- | --- | --- |
|
||
| `Deny` | bool | `true` ise alan **hiç dönmez**; diğer anahtarlara bakılmaz |
|
||
| `C` · `R` · `U` | string | Yaratma / okuma / güncelleme yetkisinin **adı**. Boşsa ekranın kendi Create/Read/Update yetkisi kullanılır |
|
||
| `E` | bool | Alan dışa aktarımda yer alsın mı |
|
||
| `I` | bool | Alan içe aktarımda kabul edilsin mi |
|
||
|
||
```json
|
||
{ "C": "App.Mrp.Orders.Create", "R": "App.Mrp.Orders", "U": "App.Mrp.Orders.Update",
|
||
"E": true, "I": true, "Deny": false }
|
||
```
|
||
|
||
`ListFormField` üzerindeki `CanRead` / `CanCreate` / `CanUpdate` / `CanExport` kolonları
|
||
**veritabanında yoktur** (`[NotMapped]`); `ListFormFieldManager.SetPermissionsAsync` bu
|
||
JSON'u oturumdaki yetkilerle karşılaştırarak istek başına hesaplar. Üçü de `false` çıkan alan
|
||
metadata'dan tamamen düşer — yani okuma yetkisi olmayan bir kolon sorguya bile girmez.
|
||
Wizard varsayılan olarak `DefaultFieldPermissionJson(permissionName)` üretir.
|
||
|
||
### 5.2 `SubFormsJson` (`SubFormDto[]`)
|
||
|
||
| Anahtar | Anlam |
|
||
| --- | --- |
|
||
| `TabType` | Sekmenin görünümü — `ListFormTabTypeEnum`: `List` \| `Card` \| `Tree` \| `Gantt` \| `Scheduler` \| `Todo` \| `Form` \| `Chart` \| `Pivot` |
|
||
| `TabTitle` | Dil anahtarı |
|
||
| `Code` | Hedef `ListFormCode` |
|
||
| `IsRefresh` | Ana kayıt değişince yenilensin |
|
||
| `Relation[]` | `ParentFieldName` → `ChildFieldName` + `DbType` (`System.Data.DbType`, **sayı**; bileşik anahtarda birden çok satır) |
|
||
|
||
Alt formun kendisi de bir ListForm'dur: `IsSubForm = true` olmalı ve genellikle `CreateMenu:
|
||
false` ile menüsüz üretilir (`lowcode` §4.2). `TabType`, hedef ekranın `LayoutJson`'ında açık
|
||
olan bir görünüm olmalıdır; kapalı bir görünüm sekmede boş çizilir.
|
||
|
||
### 5.3 `WidgetsJson` (`WidgetEditDto[]`)
|
||
|
||
Ekranın üstündeki KPI şeridi. **Sözleşmesi sezgisel değildir, dikkatle oku:**
|
||
|
||
| Anahtar | Ne yazılır |
|
||
| --- | --- |
|
||
| `SqlQuery` | Kartları besleyen sorgu. **Zorunludur** — boş olan widget hiç çizilmez |
|
||
| `Title` · `SubTitle` · `Value` · `Color` · `Icon` · `OnClick` | **Sorgu sonucundaki kolon adları** — sabit metin değil. Sunucu her satırda bu adlı kolonu okur; kolon yoksa boş string döner |
|
||
| `ColSpan` · `ColGap` · `ClassName` | Şeritteki yerleşim (widget başına, karta değil) |
|
||
| `ValueClassName` | Değerin CSS sınıfı, varsayılan `text-3xl` |
|
||
| `IsActive` | `false` ise sorgu hiç çalıştırılmaz |
|
||
|
||
**Bir widget, sorgunun döndürdüğü her satır için bir kart çizer.** Yani tek bir widget kaydıyla
|
||
"Bekleyen / Onaylı / Reddedilen" üçlüsü tek sorgudan üretilebilir:
|
||
|
||
```sql
|
||
SELECT 'Bekleyen' AS Baslik, COUNT(*) AS Deger, 'amber' AS Renk, 'FaClock' AS Ikon
|
||
FROM Mrp_T_Order WHERE Status = 1
|
||
UNION ALL
|
||
SELECT 'Onaylı', COUNT(*), 'green', 'FaCheck' FROM Mrp_T_Order WHERE Status = 2
|
||
```
|
||
|
||
```json
|
||
{ "Title": "Baslik", "Value": "Deger", "Color": "Renk", "Icon": "Ikon", "ColSpan": 4, "IsActive": true }
|
||
```
|
||
|
||
Sorgu ekranın `DataSourceCode` bağlantısında, **olduğu gibi** çalıştırılır:
|
||
|
||
- Ekranın otomatik tenant/şube/OU filtresi **uygulanmaz**.
|
||
- `@USERID` / `@TENANTID` gibi token'lar **çözülmez** — bunlar `*FieldsDefaultValueJson` ve
|
||
`DefaultFilter` yolunun sözleşmesidir. Widget sorgusuna yazılırsa bağlanmamış parametre
|
||
hatası verir. Kiracı kırılımı gerekiyorsa ya kiracıya özel bir `DataSource` kullan, ya da
|
||
kırılımı sorgunun okuduğu view'ın içine göm.
|
||
|
||
### 5.4 `LayoutJson` (`LayoutDto`)
|
||
|
||
| Anahtar | Varsayılan |
|
||
| --- | --- |
|
||
| `Grid` · `Card` · `Pivot` · `Chart` · `Tree` · `Gantt` · `Scheduler` | `true` |
|
||
| `Todo` | `false` |
|
||
| `DefaultLayout` | `"grid"` |
|
||
|
||
Wizard'daki görünüm bayraklarının karşılığıdır. **DTO varsayılanları yanıltıcıdır:** blok
|
||
yazılmazsa yedi görünüm birden açık gelir; ekranın üstünde çalışmayan görünüm düğmeleri
|
||
çıkmasın diye wizard bu bloğu her zaman açıkça yazar. `DefaultLayout`, `true` olan bir görünümü
|
||
göstermelidir (§7'deki zorunlu `*Expr` alanları boşsa o görünümün JSON'u hiç yazılmaz).
|
||
|
||
### 5.5 `CustomJsSourcesJson` / `CustomStyleSourcesJson`
|
||
|
||
Her ikisi de **string dizisidir**. Bir eleman `http` ya da `/` ile başlıyorsa dosya olarak
|
||
sayfaya eklenir (`<script src>` / `<link rel=stylesheet>`); aksi hâlde içerik olarak çalıştırılır
|
||
(JS'te `eval`, CSS'te inline `<style>`).
|
||
|
||
```json
|
||
["/assets/custom/orders.js", "console.log('orders ekranı yüklendi')"]
|
||
```
|
||
|
||
**Son çaredir.** Önce `EditorScript`, `EditorOptions`, `ColumnStylingJson` ve `CommandColumnJson`
|
||
denenir. Buraya yazılan kod ekran her açıldığında çalışır ve hiçbir yerde denetlenmez.
|
||
|
||
### 5.6 Ekranın türü
|
||
|
||
| Kolon | Varsayılan | Anlam |
|
||
| --- | --- | --- |
|
||
| `ListFormType` | `"List"` | `ListFormTypeEnum`: `List` (ızgara) \| `Form` (tek kayıt) \| `Chart` (yalnız grafik). Route karşılıkları: `/admin/list/{kod}` · `/admin/form/{kod}[/{id}[/edit]]` · `/admin/chart/{kod}` |
|
||
| `IsSubForm` | `false` | Ekran alt form olarak da kullanılıyor mu |
|
||
| `SubFormsListFormType` | `"Form"` | Alt form olarak açıldığında hangi görünümle geleceği |
|
||
| `ShowNote` | `true` | Not paneli (alt form ya da iş akışı varsa wizard açar) |
|
||
|
||
`ListFormType = "Form"` listesiz, tek kayıtlık kart ekrandır; canlı örneği Administration ›
|
||
Licence'tır (§12.6). `Pivot` bir `ListFormType` **değildir** — pivot, `LayoutJson.Pivot`
|
||
bayrağıyla açılan bir görünümdür ve `/admin/pivot/...` diye bir route yoktur.
|
||
|
||
### 5.7 Varyantlar
|
||
|
||
Aynı `ListFormCode` ile ikinci bir `ListForm` kaydı açılıp `CultureName`, `UserId` ya da `RoleId`
|
||
doldurulursa o dil/kullanıcı/rol için **farklı sütun düzeni ve ayarlar** verilebilir. Aynı şey
|
||
`ListFormField` ve `Menu` kayıtları için de geçerlidir. Wizard bunu üretmez; ihtiyaç varsa
|
||
ListForm editöründen açılır ve seed karşılığı elle yazılır.
|
||
|
||
---
|
||
|
||
## 6. Pivot
|
||
|
||
### 6.1 `PivotOptionJson` (`GridPivotOptionDto`)
|
||
|
||
| Anahtar | Varsayılan |
|
||
| --- | --- |
|
||
| `ShowFieldPanel` | `true` |
|
||
| `AllowFieldDragging` | `true` |
|
||
| `ShowDataFields` / `ShowColumnFields` / `ShowRowFields` / `ShowFilterFields` | `true` |
|
||
| `ColumnChooserEnabled` | `false` |
|
||
| `ShowChart` | `false` |
|
||
| `ChartHeight` | `320` |
|
||
| `ChartCommonSeriesType` | `"bar"` |
|
||
|
||
### 6.2 Alan başına `PivotSettingsJson` (`ListFormFieldPivotSettingsDto`)
|
||
|
||
| Anahtar | Varsayılan | Değerler |
|
||
| --- | --- | --- |
|
||
| `IsPivot` | `true` | Alan pivotta kullanılsın mı |
|
||
| `Area` | `filter` | `row` \| `column` \| `data` \| `filter` |
|
||
| `SummaryType` | — | `sum` \| `avg` \| `count` \| `min` \| `max` |
|
||
| `GroupInterval` | `none` | `day` \| `dayOfWeek` \| `month` \| `quarter` \| `year` |
|
||
| `SortOrder` | `asc` | `asc` \| `desc` |
|
||
| `Format` | — | DevExtreme format adı |
|
||
| `Expanded` | `false` | Başlangıçta açık |
|
||
| `WordWrapEnabled` | `false` | |
|
||
|
||
Pivot ekranı ayrı bir sorgu istemez; ızgarayla aynı `SelectCommand` üzerinden çalışır.
|
||
|
||
---
|
||
|
||
## 7. Ağaç, Gantt, Takvim, Kanban
|
||
|
||
### 7.1 `TreeOptionJson` (`TreeOptionDto`)
|
||
|
||
`KeyExpr`*, `ParentIdExpr`*, `HasItemsExpr`, `RootValue` (varsayılan `null`),
|
||
`ExpandedRowKeys[]`, `AutoExpandAll` (`false`), `RecursiveSelection` (`false`),
|
||
`TitleExpr`, `StartExpr`, `EndExpr`, `ProgressExpr`.
|
||
|
||
### 7.2 `GanttOptionJson` (`GanttOptionDto`)
|
||
|
||
Ağaç alanlarının tamamı + `TitleExpr`*, `StartExpr`*, `EndExpr`*, `ProgressExpr`,
|
||
`ScaleType` (varsayılan `weeks`; tam küme `GanttScaleTypeEnum`: `auto` \| `minutes` \| `hours` \|
|
||
`sixHours` \| `days` \| `weeks` \| `months` \| `quarters` \| `years`) ve izin bayrakları:
|
||
`AllowEditing`, `AllowTaskAdding`, `AllowTaskUpdating`, `AllowTaskResourceUpdating`,
|
||
`AllowTaskDeleting`, `AllowDependencyAdding`, `AllowDependencyDeleting`, `AllowResourceAdding`,
|
||
`AllowResourceUpdating`, `AllowResourceDeleting` (hepsi `false`).
|
||
|
||
### 7.3 `SchedulerOptionJson` (`SchedulerOptionDto`)
|
||
|
||
| Anahtar | Varsayılan | Anlam |
|
||
| --- | --- | --- |
|
||
| `TextExpr`* · `StartDateExpr`* · `EndDateExpr`* | — | Başlık ve zaman kolonları |
|
||
| `UserNameExpr` · `DescriptionExpr` | — | Kaynak/kişi ve açıklama |
|
||
| `AllDayExpr` | — | Tüm gün bayrağı kolonu |
|
||
| `RecurrenceRuleExpr` · `RecurrenceExceptionExpr` | — | Tekrar kuralı kolonları |
|
||
| `StartDayHour` / `EndDayHour` | `8` / `20` | Görünen saat aralığı |
|
||
| `DefaultView` | `"week"` | Ekranın çizdiği sekiz görünüm: `day` \| `week` \| `workWeek` \| `month` \| `timelineDay` \| `timelineWeek` \| `timelineMonth` \| `agenda` |
|
||
| `ShowAllDayPanel` | `true` | |
|
||
| `CellDuration` | `30` | Hücre dakikası |
|
||
| `FirstDayOfWeek` | `1` | 0 = Pazar |
|
||
| `CrossScrollingEnabled` | `false` | Kaynak (resource) görünümünde yatay+dikey kaydırma |
|
||
| `AllowAdding` / `AllowEditing` / `AllowDeleting` / `AllowDragging` / `AllowResizing` | `false` | |
|
||
| `Resources[]` | — | Randevuları renklendiren kaynak eşlemesi (`FieldExpr`, `DataSource[]`, `Label`, `UseColorAsDefault`) |
|
||
|
||
`Resources` C# `SchedulerOptionDto`'da **tanımlı değildir**; yalnızca UI modelinde (`proxy/form/
|
||
models.ts`) vardır. Yani seed'den yazılabilir (bilinmeyen anahtar korunur ve bileşene geçer) ama
|
||
ListForm editöründeki tipli formdan düzenlenemez; kalıcı kullanılacaksa C# DTO'suna eklenmelidir.
|
||
|
||
### 7.4 `TodoOptionJson` (`TodoOptionDto`) — Kanban
|
||
|
||
`TitleExpr`*, `StatusExpr`*, `DescriptionExpr`, `DueDateExpr`, `TagExpr`, `AssigneeExpr`,
|
||
`PriorityExpr`, `CompletedExpr`, `OrderExpr`, `TimesheetExpr`, `SubTaskExpr`,
|
||
`StatusOrder` (kolon sırası, virgüllü), `AllowDragging` (varsayılan `true`).
|
||
|
||
> `*` işaretli alan boşsa seeder o görünümün JSON'unu **yazmaz**; bayrağı açmak yetmez.
|
||
|
||
---
|
||
|
||
## 8. Chart (grafik) sözleşmesi
|
||
|
||
Grafik, ListForm üzerindeki **22 ayrı JSON kolonuyla** yapılandırılır. Hepsi DevExtreme
|
||
`dxChart` yapılandırmasının karşılık gelen bölümüne geçer — ama tipli DTO'dan süzülerek
|
||
(girişteki "bilinmeyen anahtar düşer" kuralı grafik kolonları için de geçerlidir).
|
||
|
||
Grafik iki yoldan açılır: ekranın `LayoutJson.Chart` bayrağıyla bir görünüm olarak, ya da
|
||
`ListFormType = "Chart"` ile yalnız grafikten oluşan bir ekran (`/admin/chart/{kod}`) olarak.
|
||
|
||
| Kolon | Karşılığı |
|
||
| --- | --- |
|
||
| `SeriesJson` | `series[]` — **zorunlu**, §8.1 |
|
||
| `DataSourceJson` | Grafiğin kendi sorgusu, §8.2 |
|
||
| `CommonJson` | Grafik geneli (palet, tema), §8.3 |
|
||
| `CommonSeriesSettingsJson` | Tüm serilere ortak ayarlar |
|
||
| `ArgumentAxisJson` · `ValueAxisJson` · `CommonAxisSettingsJson` | Eksenler, §8.5 |
|
||
| `LegendJson` | Açıklama kutusu, §8.6 |
|
||
| `TooltipJson` | İpucu balonu, §8.7 |
|
||
| `PanesJson` · `CommonPaneSettingsJson` | Bölmeler (çok panelli grafik) |
|
||
| `AnnotationsJson` · `CommonAnnotationsSettingsJson` | Ek açıklamalar |
|
||
| `CrosshairJson` | Artı imleç çizgileri |
|
||
| `ScrollBarJson` | Kaydırma çubuğu |
|
||
| `ZoomAndPanJson` | Yakınlaştırma/kaydırma |
|
||
| `SizeJson` · `MarginJson` · `AdaptiveLayoutJson` | Boyut, kenar boşluğu, dar ekran davranışı |
|
||
| `TitleJson` | Başlık/alt başlık |
|
||
| `AnimationJson` | Animasyon |
|
||
| `ExportJson` | Dışa aktarma/yazdırma |
|
||
|
||
Ayrıca grafiğe **kullanıcı/rol kısıtı**: ListForm kaydındaki `UserId` / `RoleId` alanları boşsa
|
||
grafik herkese açıktır.
|
||
|
||
### 8.1 `SeriesJson` (`ChartSeriesDto[]`)
|
||
|
||
| Anahtar | Varsayılan | Anlam |
|
||
| --- | --- | --- |
|
||
| `Name` | — | Açıklamada görünen seri adı |
|
||
| `Type` | `line` | `line` \| `bar` \| `spline` \| `area` \| `scatter` \| `bubble` \| `stackedbar` \| `fullstackedbar` \| `stackedline` \| `stackedarea` \| `steparea` \| `stepline` \| `rangebar` \| `rangearea` \| `candlestick` \| `stock` ve stacked/fullstacked varyantları |
|
||
| `ArgumentField` | `"arg"` | X ekseni kolonu |
|
||
| `ValueField` | — | Y ekseni kolonu |
|
||
| `SummaryType` | `"sum"` | `sum` \| `avg` \| `count` \| `min` \| `max` \| `custom` |
|
||
| `Color` | — | Seri rengi |
|
||
| `Axis` · `Pane` | — | Hangi eksen/bölme |
|
||
| `Visible` | `true` | |
|
||
| `ShowInLegend` | `true` | |
|
||
| `Width` | `2` | Çizgi kalınlığı |
|
||
| `DashStyle` | `"solid"` | `solid` \| `dash` \| `dot` \| `longDash` |
|
||
| `BarWidth` · `BarPadding` · `BarOverlapGroup` · `CornerRadius` | — | Çubuk serileri |
|
||
| `IgnoreEmptyPoints` | `false` | |
|
||
| `SelectionMode` | `"none"` | `onlyPoint` \| `allSeriesPoints` \| `allArgumentPoints` \| `includePoints` \| `excludePoints` \| `none` |
|
||
| `RangeValue1Field` / `RangeValue2Field` | `val1` / `val2` | Aralık serileri |
|
||
| `Label` | — | `ChartLabelDto`: `Visible`, `Format`, `Font`, `BackgroundColor`, `CustomizeText` |
|
||
| `UserId` | — | Seriyi yalnızca bu kullanıcıya göster |
|
||
|
||
### 8.2 `DataSourceJson` (`ChartDataSourceDto`)
|
||
|
||
```json
|
||
{ "Query": "SELECT Status AS arg, SUM(Amount) AS val FROM Mrp_T_Order GROUP BY Status" }
|
||
```
|
||
|
||
Grafik, ızgaranın `SelectCommand`'ından **ayrı** bir sorgu kullanabilir. Sorgu kolonları
|
||
`ArgumentField` / `ValueField` adlarıyla eşleşmelidir. Ekranın filtresi grafik isteğine
|
||
`Filter` parametresi olarak taşınır.
|
||
|
||
### 8.3 `CommonJson` (`ChartCommonDto`)
|
||
|
||
| Anahtar | Varsayılan | Anlam |
|
||
| --- | --- | --- |
|
||
| `Palette` | `"Material"` | `Bright` \| `Harmony Light` \| `Ocean` \| `Pastel` \| `Soft` \| `Soft Pastel` \| `Vintage` \| `Violet` \| `Carmine` \| `Dark Moon` \| `Dark Violet` \| `Green Mist` \| `Soft Blue` \| `Material` \| `Office` |
|
||
| `PaletteExtensionMode` | `"blend"` | `alternate` \| `blend` \| `extrapolate` |
|
||
| `Theme` | `"generic.light"` | `generic.*` ve `material.*.light` varyantları |
|
||
| `ContainerBackgroundColor` | `"#FFFFFF"` | |
|
||
| `AdjustOnZoom` | `true` | |
|
||
| `DefaultPane` | — | |
|
||
| `Disabled` | `false` | |
|
||
|
||
### 8.4 Boyut ve yerleşim
|
||
|
||
- `SizeJson` (`ChartSizeDto`): `UseSize` (`false`), `Width` (`400`), `Height` (`200`).
|
||
`UseSize: false` iken grafik kapsayıcıya yayılır.
|
||
- `MarginJson` (`ChartMarginDto`): `Top`, `Bottom`, `Left`, `Right`.
|
||
- `AdaptiveLayoutJson` (`ChartAdaptivelayoutDto`): `Width`/`Height` eşiği (`80`/`80`),
|
||
`KeepLabels` (`true`).
|
||
- `TitleJson` (`ChartTitleDto`): `Text`, `Subtitle`, `HorizontalAlignment` (`center`),
|
||
`VerticalAlignment` (`top`), `TextOverflow` (`ellipsis`), `WordWrap`.
|
||
- `AnimationJson` (`ChartAnimationDto`): `Enabled` (`true`), `Duration` (`1000`),
|
||
`Easing` (`easeOutCubic` \| `linear`), `MaxPointCountSupported` (`300`).
|
||
- `ExportJson` (`ChartExportDto`): `Enabled`, `PrintingEnabled` (`true`),
|
||
`AllowExportSelectedData`, `BackgroundColor` (`#ffffff`), `Margin` (`10`).
|
||
|
||
### 8.5 Eksenler
|
||
|
||
`ArgumentAxisJson` (`ChartArgumentAxisDto`): `ArgumentType` (`datetime` \| `numeric` \| `string`),
|
||
`AggregationInterval` (`day` \| `hour` \| `minute` \| `month` \| `quarter` \| `second` \| `week` \| `year`),
|
||
`Position` (`bottom` \| `left` \| `right` \| `top`), `HoverMode` (`none` \| `allArgumentPoints`),
|
||
`Grid`, `Label` → `DisplayMode` (`standard` \| `rotate` \| `stagger`), `RotationAngle` (`90`),
|
||
`OverlappingBehavior` (`hide` \| `rotate` \| `stagger` \| `none`).
|
||
|
||
`ValueAxisJson` (`ChartValueAxisDto`): `Name`, `Title`, `ValueType` (`numeric`),
|
||
`Position` (`left`), `Type` (`continuous` \| `discrete` \| `logarithmic`), `Visible` (`true`),
|
||
`Width` (`1`), `Grid`, `Breaks[]`, `BreakStyle`, `AutoBreaksEnabled` (`true`),
|
||
`MaxAutoBreakCount` (`2`).
|
||
|
||
`CommonAxisSettingsJson` iki eksene birden uygulanır; **eksene özel ayar varsa yok sayılır.**
|
||
|
||
### 8.6 `LegendJson` (`ChartLegendDto`)
|
||
|
||
`Visible` (`true`), `Position` (`outside` \| `inside`), `Orientation` (`vertical` \| `horizontal`),
|
||
`ColumnCount`, `RowCount`, `Title`, `BackgroundColor`, `Border`.
|
||
|
||
### 8.7 `TooltipJson` (`ChartTooltipDto`)
|
||
|
||
`Enabled`, `Shared`, `Format` / `ArgumentFormat` (DevExtreme format adları),
|
||
`Color` (`#ffffff`), `ArrowLength` (`10`), `Location` (`center` \| `edge`),
|
||
`PaddingLeftRight` (`18`), `PaddingTopBottom` (`15`), `Border`, `Font`.
|
||
|
||
### 8.8 Diğerleri
|
||
|
||
- `PanesJson` (`ChartPanesDto[]`): `Name`, `Height` (`250`), `BackgroundColor`.
|
||
Seriler `Pane` alanıyla bir bölmeye bağlanır.
|
||
- `CrosshairJson` (`ChartCrosshairDto`): `Enabled`, `Color` (`#f05b41`), `Width` (`1`),
|
||
`DashStyle` (`dot`), `HorizontalLine`, `VerticalLine`, `Label`.
|
||
- `ScrollBarJson` (`ChartScrollBarDto`): `Visible`, `Position` (`top`), `Color` (`gray`),
|
||
`Width` (`10`), `Offset` (`5`).
|
||
- `ZoomAndPanJson` (`ChartZoomAndPanDto`): `ArgumentAxis` / `ValueAxis`
|
||
(`none` \| `pan` \| `zoom` \| `both`), `AllowMouseWheel` (`true`), `AllowTouchGestures` (`true`),
|
||
`DragToZoom` (`false`), `PanKey` (`shift`), `DragBoxStyle`.
|
||
- `AnnotationsJson` (`ChartAnnotationDto[]`): `Name`, `Text`, `Image`, `Series`, `Argument`,
|
||
`OffsetX`/`OffsetY`, `Color`, `Font`, `Border`, `TooltipEnabled`, `Description`.
|
||
|
||
---
|
||
|
||
## 9. Alan (`ListFormField`) JSON kolonları
|
||
|
||
`lowcode` §4.3.4–4.3.7'de anlatılan `LookupJson`, `ValidationRuleJson`, `ColumnStylingJson`
|
||
dışında kalanlar:
|
||
|
||
### 9.1 `ColumnFilterJson` (`ColumnFilterDto`)
|
||
|
||
| Anahtar | Anlam |
|
||
| --- | --- |
|
||
| `AllowFiltering` | Bu sütun filtrelenebilsin mi (`true`) |
|
||
| `FilterOperations[]` | İzin verilen operatörler; boş bırakılırsa tipe göre otomatik. Değerler: `=`, `<>`, `<`, `<=`, `>`, `>=`, `contains`, `notcontains`, `startswith`, `endswith`, `isblank`, `isnotblank`, `between`, `anyof`, `noneof` |
|
||
| `SelectedFilterOperation` | Varsayılan seçili operatör |
|
||
| `FilterValue` | Ekran açılırken uygulanan filtre değeri |
|
||
|
||
### 9.2 `ColumnHeaderJson` (`ColumnHeaderDto`)
|
||
|
||
`AllowHeaderFiltering` (`true`), `AllowSearch` (`false`) ve **özel başlık filtresi listesi**:
|
||
|
||
```json
|
||
{ "AllowHeaderFiltering": true,
|
||
"DataSource": [ { "text": "3000 altı", "value": ["Amount", "<", 3000] },
|
||
{ "text": "3000 üstü", "value": ["Amount", ">=", 3000] } ] }
|
||
```
|
||
|
||
### 9.3 `GroupingJson` (`ColumnGroupingDto`)
|
||
|
||
`AllowGrouping` (`true`), `GroupIndex` (kaçıncı seviyeden gruplanacağı), `AutoExpandGroup` (`false`).
|
||
`GroupIndex` verilen sütun ekran açılışında gruplanmış gelir.
|
||
|
||
### 9.4 `ColumnCustomizationJson` (`ColumnCustomizationDto`)
|
||
|
||
`Fixed` (`false`), `FixedPosition` (`left` \| `right`), `AllowReordering` (`false`).
|
||
Sol/sağa sabitlenmiş kolon yatay kaydırmada sabit kalır.
|
||
|
||
### 9.5 `TotalSummaryJson` / `GroupSummaryJson` (`ColumnTotalSummaryDto`)
|
||
|
||
| Anahtar | Anlam |
|
||
| --- | --- |
|
||
| `SummaryType` | `sum` \| `avg` \| `count` \| `min` \| `max` \| `custom` |
|
||
| `ValueFormat` | DevExtreme format adı (`fixedPoint`, `currency`, `percent`, `shortDate`…) |
|
||
| `DisplayFormat` | Metin şablonu: `{0}` biçimlenmiş değer, `{1}` `ShowInColumn`'daki sütunun başlığı |
|
||
| `ShowInColumn` | Özetin hangi sütunun altında görüneceği (kolon adı). `DisplayFormat`'taki `{1}` bunun başlığıdır |
|
||
| `ShowInGroupFooter` | `false` — grup alt bilgisinde göster (yalnızca `GroupSummaryJson`) |
|
||
| `AlignByColumn` | `false` — grup satırında ilgili sütunun altına hizala; `false` iken özet grup başlığının yanında parantez içinde çıkar |
|
||
|
||
`TotalSummaryJson` listenin altındaki toplam satırını, `GroupSummaryJson` grup kırılımındaki
|
||
özeti üretir; ikisi de **aynı DTO'yu** kullanır, fark yazıldıkları kolondur.
|
||
|
||
"Listenin altında toplam görünsün" isteği budur; ayrı sorgu ya da widget gerekmez.
|
||
|
||
### 9.6 `JoinTableJson` (`JoinTableDto`)
|
||
|
||
Bir kolonu **başka bir tablodan** çekmek için; view yazmadan tek alanlık join kurar.
|
||
|
||
| Anahtar | Anlam |
|
||
| --- | --- |
|
||
| `JoinType` | `INNER JOIN` \| `LEFT JOIN` \| `RIGHT JOIN` |
|
||
| `TableName` | Join kurulacak tablo |
|
||
| `BaseTableJoinFieldName` | Ana tablonun join alanı |
|
||
| `JoinFieldName` | Join kurulan tablonun ilişkili alanı |
|
||
| `SelectFieldName` | Ekranda gösterilecek alan |
|
||
| `FieldNameAlias` | Alanın takma adı |
|
||
| `JoinCondition2` | İkinci koşulun bağlacı (`AND` \| `OR`) |
|
||
| `JoinFieldName2` | İkinci koşulun alanı — **tablo adıyla birlikte** (`Def_T_City.CultureName`) |
|
||
| `BaseTableJoinFieldName2_OrValue` | İkinci koşulun karşı tarafı: tablo adlı bir alan ya da `'en'` gibi sabit |
|
||
|
||
Üç-dört join'i geçen ihtiyaçta view tasarımcısı tercih edilir (`lowcode` §8.2).
|
||
|
||
### 9.7 Diğer alan kolonları
|
||
|
||
| Kolon | Varsayılan | Anlam |
|
||
| --- | --- | --- |
|
||
| `FieldName` | — | Kaynaktaki sütun adı; SQL'deki adıyla birebir |
|
||
| `CaptionName` | — | Sütun başlığı — **dil anahtarı** |
|
||
| `PlaceHolder` | — | Editörün placeholder metni |
|
||
| `Alignment` | `"left"` | `left` \| `center` \| `right` |
|
||
| `Format` | — | Hücre biçimi (DevExtreme format adı ya da desen) |
|
||
| `BandName` | — | Sütunu bir başlık bandının altına toplar |
|
||
| `Width` · `ListOrderNo` | — | Genişlik ve grid'deki sıra |
|
||
| `Visible` | — | Sütun grid'de görünür mü; `false` ise kolon seçicide durur ama **sorguya girer** |
|
||
| `IsActive` | `true` | `false` olan alan **sorguya bile girmez** |
|
||
| `SortIndex` · `SortDirection` | — | Açılıştaki sıralama (`asc` \| `desc`); çok sütunlu sıralamada `SortIndex` sırası belirler |
|
||
| `AllowSearch` · `AllowEditing` · `AllowAdding` | `true` | Arama paneline dâhil olma, güncellemede ve yeni kayıtta düzenlenebilirlik |
|
||
| `ColumnCssClass` · `ColumnCssValue` | — | Koşulsuz stil (sınıf adı + sınıfın içeriği); koşullu olan `ColumnStylingJson` |
|
||
| `SourceDbType` | `16` String | Kolonun `System.Data.DbType` karşılığı |
|
||
| `EditorType2` · `EditorOptions` · `EditorScript` | — | Editör tipi ve davranışı (`lowcode` §5, §6) |
|
||
| `ColSpan` · `EditOrderNo` · `EditGroupOrderNo` | — | Düzenleme formundaki yeri; `EditGroupOrderNo` `EditingFormJson`'daki `Order` ile eşleşir |
|
||
| `PermissionJson` | — | Alan yetkileri (§5.1) |
|
||
| `CultureName` · `UserId` · `RoleId` | — | Alan varyantı (§5.7) |
|
||
|
||
> **`DefaultValue` / `DefaultValueType` / `ReadOnly` diye bir alan kolonu yoktur.**
|
||
> Varsayılan değerler ekran seviyesindeki `Insert/Update/Delete/Form/SelectFieldsDefaultValueJson`
|
||
> bloklarında, alan adıyla eşleşen `FieldsDefaultValueDto` satırları olarak durur
|
||
> (`lowcode` §4.3.5); salt okunurluk ise `EditorOptions.readOnly` ya da `EditorScript`'in
|
||
> `readOnly` tarifidir (`lowcode` §6.6).
|
||
|
||
### 9.8 Tipli editör seçenekleri
|
||
|
||
`EditorOptions` JSON'unun bazı anahtarları backend'de **tipli DTO'ya** çözülür; yanlış tip
|
||
sessizce yok sayılır:
|
||
|
||
| DTO | Hangi `EditorType2` | Anahtarlar (varsayılan) |
|
||
| --- | --- | --- |
|
||
| `GridBoxOptionsDto` | `dxGridBox` | `Columns[]` (ilk kolon `Key` ile aynı adda olmalı), `SelectionMode` (`"single"`), `FilterRowVisible` (`false`), `AcceptCustomValue` (`false`), `ShowClearButton` (`true`), `Height` (`250`), `Width` (`500`) |
|
||
| `TagBoxOptionsDto` | `dxTagBox` | `ShowSelectionControls` (`true`), `MaxDisplayedTags` (`3`), `ShowMultiTagOnly` (`false`), `ApplyValueMode` (`"useButtons"`), `SearchEnabled` (`true`), `AcceptCustomValue` (`false`), `ShowClearButton` (`true`) — değer tek kolonda `\|` ile saklanır, bkz. §4.3 |
|
||
| `ImageUploadOptionsDto` | `dxImageUpload` · `dxImageViewer` | `UploadUrl`, `Accept`, `Multiple`, `MaxFileSize` (bayt), `Width`, `Height` — hepsi nullable, varsayılanı yok |
|
||
|
||
Çözüm **yalnızca alanın `EditorType2` değeri eşleşiyorsa** yapılır: `dxTextBox` bir alana
|
||
`columns` yazmak `GridBoxOptions`'ı doldurmaz. Ayrıca `ListFormField.EditorOptions`'ın ham
|
||
metni istemciye **her hâlükârda** gider; tipli DTO'lar onun yanında ek bir kolaylıktır ve
|
||
`JsonException` durumunda sessizce `null` döner — yani bozuk JSON burada ekranı düşürmez, ama
|
||
tipli okumaya bağlı davranış (GridBox kolonları, TagBox etiket sayısı) çalışmaz.
|
||
|
||
---
|
||
|
||
## 10. Visual Designer envanteri
|
||
|
||
`lowcode` §7 tasarımcı dokümanının şemasını anlatır; burada **kutuda ne olduğu** listelenir.
|
||
|
||
### 10.1 Toolbox aileleri
|
||
|
||
Kutunun içeriği tek bir yerden, `getDesignerCatalog()` (`components/visualDesigner/catalog.ts`)
|
||
tarafından üretilir: elle yazılmış tanımlar + `components/ui` altındaki bileşenlerden
|
||
otomatik çıkarılan metadata (`generated/componentProps.json`).
|
||
|
||
| Aile | Bileşenler |
|
||
| --- | --- |
|
||
| `layout` | `PageContainer` (maxWidth, padding, gap, className), `FlexRow` (columns, firstColumnWidth, gap, wrap, align, className), `Table` |
|
||
| `data` | `Form` (§10.2) ve veri bağlanabilen UI bileşenleri: `Select`, `AutoComplete`, `Dropdown`, `Menu`, `Pagination`, `Radio.Group`, `Tabs`, `Grid` |
|
||
| `platform` | `ListView`, `DataGridView`, `TreeView`, `GanttView`, `TodoBoard`, `CardView`, `SchedulerView`, `PivotView`, `ChartView` — hepsi aynı üç prop'u alır: `listFormCode` (**zorunlu**), `height` (varsayılan `520px`, `ChartView`'da `420px`), `className` |
|
||
| `html` | `div`, `p`, `span`, `h1`, `h2`, `h3`, `h4`, `h5`, `img` — **yalnız bu dokuz etiket** |
|
||
| `ui` | `Avatar`, `Badge`, `Button`, `Calendar`, `Card`, `Checkbox`, `Chips`, `ColorPicker`, `DatePicker`, `ImageViewer`, `Input`, `Knob`, `Marquee`, `Notification`, `Progress`, `Radio`, `RangeCalendar`, `Rate`, `ScrollBar`, `Skeleton`, `Slider`, `Spacer`, `Spinner`, `Switcher`, `Tag`, `TimeInput`, `Tooltip`, `Upload` |
|
||
| `custom` | Kayıtlı diğer custom component'ler (`Dependencies`'e eklenir) |
|
||
|
||
**`input`, `button`, `textarea`, `select`, `checkbox` HTML etiketleri kutuda yoktur**
|
||
(`HTML_UI_DUPLICATES`): karşılıkları `ui` ailesindeki `Input`, `Button`, `Select`, `Checkbox`
|
||
bileşenleridir; ham etiket bırakmaya çalışma, tema ve doğrulama onlardan gelir.
|
||
|
||
Kutu dışında tutulanlar (`EXCLUDED_COMPONENTS`): `Alert`, `Breadcrumb`, `Dialog`, `Drawer`,
|
||
`FormContainer`, `FormItem`, `InputGroup`, `MenuItem`, `Segment`, `Steps`. Bunlara ihtiyaç
|
||
duyan bir yerleşim, tasarımcı yerine **Code modunda** yazılır (`lowcode` §7.1.1) — orada
|
||
`components/ui`'nin tamamı kapsamdadır.
|
||
|
||
Çocuk düğüm kabul edenler: `PageContainer`, `FlexRow`, `Form`, `div`, `Card`, `Table`, `Tabs`
|
||
ve **her custom component**. Diğer düğümlerin içine bırakma; kanvas kabul etse de üretilen kod
|
||
çocukları çizmez.
|
||
|
||
Düğüm başına iki ortak prop, hangi ailede olursa olsun geçerlidir:
|
||
|
||
| Prop | Anlam |
|
||
| --- | --- |
|
||
| `designerPermission` | Boş değilse düğüm yalnızca bu yetki verilmişse **çizilir**; verisini göremeyeceği bir grid hiç oluşturulmaz |
|
||
| `className` | Tailwind sınıfları |
|
||
|
||
> **Önce yeniden kullan:** İstenen şey bir ListForm ekranının verdiği liste/ağaç/pano/grafikse
|
||
> primitiflerden kurma; `platform` düğümünü `listFormCode` ile bırak.
|
||
>
|
||
> **Eksik olan = var olan bileşene ekle, yeni bileşen yazma:** İstenen komponent bu
|
||
> envanterle büyük ölçüde kuruluyor ama bir bileşende **olay, prop ya da küçük bir yetenek**
|
||
> eksikse komponent yine üretilir: eksik parça `components/ui/{Name}`'e geriye dönük uyumlu
|
||
> eklenir, `componentProps.json` elle güncellenir, olaysa `catalog.ts` `DESIGNER_PRIMARY_EVENTS`,
|
||
> değer kümesiyse `NAMED_UNION_OPTIONS`/`PROPERTY_OVERRIDES`, sonra §10.9/§10.10 tabloları
|
||
> tamamlanır (`lowcode` §7.3 notu). Yeni `ui` bileşeni, yeni toolbox ailesi, Developer Kit
|
||
> menüsüne yeni komponent ya da var olan bileşenin davranışını değiştiren ekleme **yapılmaz** —
|
||
> bunlar çerçeve dışıdır ve onay ister (`lowcode` §0.8).
|
||
|
||
### 10.2 `Form` düğümü
|
||
|
||
Dört CRUD ucunu sahiplenen kapsayıcı. İçine bırakılan her bileşen kaydın bir kolonuna bağlanır.
|
||
|
||
| Prop | Varsayılan | Anlam |
|
||
| --- | --- | --- |
|
||
| `title` | `""` | Kart başlığı; boşsa Card başlığı hiç çizilmez (`::` önekli değer dil anahtarıdır) |
|
||
| `selectEndpoint` / `insertEndpoint` / `updateEndpoint` / `deleteEndpoint` | — | GET / POST / PUT / DELETE uçları |
|
||
| `selectPermission` / `insertPermission` / `updatePermission` / `deletePermission` | — | Komut yetkileri; boşsa dokümanın `permissionCode` değeri + `""`/`.Create`/`.Update`/`.Delete` **otomatik** çözülür (`FORM_AUTO_SUFFIXES`), o da yoksa komut açıktır |
|
||
| `keyFieldName` | `"id"` | Anahtar kolon |
|
||
| `collectionPath` | `""` | Select yanıtındaki liste yolu; boşsa yanıtın kendisi |
|
||
| `keySource` | `"query"` | `query` \| `route` — anahtarın URL'de nereden okunacağı |
|
||
| `keyParamName` | `""` | Parametre/segment adı; boşsa `route`'ta son segment kullanılır |
|
||
| `previewKeyValue` | `""` | Yalnızca tasarımcı önizlemesi; üretilen koda girmez |
|
||
| `autoLoad` | `true` | Açılışta veriyi çek |
|
||
| `showToolbar` | `true` | Kaydet/Sil/Gezinme çubuğu |
|
||
| `columnCount` | `1` | Form içindeki alanların kaç kolona diziliceği |
|
||
| `gap` | `16` | Alanlar arası boşluk (px) |
|
||
| `className` | `""` | Ek sınıflar |
|
||
|
||
Olayları ve script API'si `lowcode` §7.8'dedir. Bir sayfada birden fazla `Form` olabilir;
|
||
ana-detay için detay tarafının veri kaynağına `source: "record"` filtresi verilir ve değeri
|
||
`<anaFormRef>.<kolon>` biçiminde yazılır (§10.4).
|
||
|
||
### 10.3 Veri bileşenleri
|
||
|
||
`DESIGNER_DATA_COMPONENTS` iki tür tanır:
|
||
|
||
| Tür | Bileşenler | Koleksiyon prop'u |
|
||
| --- | --- | --- |
|
||
| `option` (etiket/değer) | `Select`, `AutoComplete`, `Dropdown`, `Menu`, `Pagination`, `Radio.Group`, `Tabs` | `options` (Select/AutoComplete) ya da `items` |
|
||
| `tabular` (satır) | `Grid` | `items` |
|
||
|
||
`option` bileşenlerinde binding'e `columns` eklenirse, ekranda görünmeyen kolonlar script'ten
|
||
`refs.<ad>.getColumn('kolon')` ile okunabilir. Bu, "müşteri seçilince vergi numarası da gelsin"
|
||
isteğinin tasarımcı tarafındaki karşılığıdır — ikinci bir istek atılmaz.
|
||
|
||
### 10.4 Veri kaynakları ve filtreler
|
||
|
||
Doküman seviyesindeki `dataSources` listesi, düğümlerin `bindings.sourceId` ile bağlandığı
|
||
uçlardır. Şeması `lowcode` §7.2'de; burada **filtre sözleşmesi** açılır.
|
||
|
||
| `source` | `value` ne demek | Ne zaman |
|
||
| --- | --- | --- |
|
||
| `static` | Değerin kendisi | Sabit kırılım (`IsActive = true`) |
|
||
| `query` | Sayfa adresindeki query parametresinin **adı** (`?id=…`) | Adresle taşınan bağlam |
|
||
| `route` | Yol segmentinin adı; boşsa **son segment** | `/admin/order/123` gibi rotalar |
|
||
| `record` | `<formRef>.<kolon>` — başka bir `Form` düğümünün aktif kaydının kolonu | Ana-detay; tek satır kod yazmadan |
|
||
|
||
| `operator` | Query string'e nasıl çıkar |
|
||
| --- | --- |
|
||
| `eq` | Çıplak parametre: `?RoleId=5` |
|
||
| `ne` `contains` `startswith` `endswith` `gt` `gte` `lt` `lte` `in` `isnull` `notnull` | Adını son ek olarak taşır: `?Name.contains=abc` |
|
||
|
||
`isnull` / `notnull` değer almaz (`DESIGNER_VALUELESS_FILTER_OPERATORS`); değer kutuları gizlenir.
|
||
|
||
`required` **varsayılan olarak `true`'dur ve bilinçlidir**: değeri henüz gelmemiş bir filtre
|
||
isteği tutar. Aksi hâlde filtresiz koleksiyon yüklenir ve bu, kullanıcıya "filtre çalışmıyor"
|
||
diye görünür. `previewValue` yalnızca tasarımcı kanvasında kullanılır, üretilen koda girmez.
|
||
|
||
Bu sözleşme CRUD Endpoint `GetList` ucunun okuduğu sözleşmenin aynısıdır (`lowcode` §9.1) —
|
||
yani tasarımcıdan kurulan filtre, sunucu tarafında ek bir şey yazmadan çalışır.
|
||
|
||
### 10.5 Property Panel — nasıl çalışır
|
||
|
||
Kanvasta seçili düğümün sağ paneli üç sekmedir ve her prop bir **kategoriye** aittir:
|
||
|
||
| Kategori | Nerede görünür | Ne taşır |
|
||
| --- | --- | --- |
|
||
| `properties` | Properties sekmesi | Davranış ve içerik prop'ları |
|
||
| `styling` | Properties sekmesi (stil grubu) | `className`, boyut, boşluk, hizalama |
|
||
| `events` | **JavaScript sekmesi** | `function` tipli prop'lar — değer değil **script** olarak düzenlenir (§7.8 · `lowcode`) |
|
||
|
||
Panelin kuralları:
|
||
|
||
- **Değer kümesi bilinen prop yazılmaz, seçilir.** `options` taşıyan (ya da tsType'ı bilinen bir
|
||
union olan) her string prop panelde açılır listeye döner (`withPickableOptions`); listede
|
||
olmayan mevcut değer korunur.
|
||
- **Olay listesi süzülür:** `DESIGNER_PRIMARY_EVENTS`'te kaydı olan bileşende yalnızca o olaylar
|
||
JavaScript sekmesinde görünür (aşağıda §10.10); kaydı olmayan bileşende bütün `function`
|
||
prop'ları listelenir.
|
||
- `field` ve `form` prop'ları panelde **hiç görünmez** (Formik'in runtime nesneleridir).
|
||
- Her düğümün panel-üstü iki ortak alanı vardır: **`ref`** (script adresi — `refs.<ad>`) ve
|
||
**`designerPermission`** (boş değilse düğüm yalnızca o yetkiyle çizilir).
|
||
- Seed dosyasına yalnızca **varsayılandan farklı** prop'ları yaz; panel dokunulmayan prop'u
|
||
dokümana koymaz.
|
||
|
||
### 10.6 `layout` bileşenleri — prop sözleşmesi
|
||
|
||
**`PageContainer`** — sayfanın dış kabı; çocuk kabul eder:
|
||
|
||
| Prop | Varsayılan | Anlam |
|
||
| --- | --- | --- |
|
||
| `maxWidth` | `"1280px"` | İçerik genişliği (CSS değeri) |
|
||
| `padding` | `24` | İç boşluk (px) |
|
||
| `gap` | `16` | Çocuklar arası dikey boşluk (px) |
|
||
| `className` | `""` | |
|
||
|
||
**`FlexRow`** — yatay bölme; çocuk kabul eder:
|
||
|
||
| Prop | Varsayılan | Anlam |
|
||
| --- | --- | --- |
|
||
| `columns` | `1` | `1` = serbest akan flex satırı; `2+` = o kadar **eşit grid kolonu** |
|
||
| `firstColumnWidth` | `""` | Yalnız kolon modunda: ilk kolonu sabitler → kenar çubuğu düzeni (`"320px"`) |
|
||
| `gap` | `16` | Kolonlar arası boşluk |
|
||
| `wrap` | `true` | Taşan çocuk alta insin mi (yalnız flex modunda) |
|
||
| `align` | `"stretch"` | `stretch` \| `start` \| `center` \| `end` |
|
||
| `className` | `""` | |
|
||
|
||
**`Table`** (`ui` kitinden, `layout` grubunda; çocuk kabul eder) — statik tablo:
|
||
`borderlessRow` (—), `compact` (`false`), `hoverable` (`true`), `overflow` (`true`),
|
||
`rowCount` (`2`), `columnCount` (`3`), `className`. `columns`/`data` prop'ları panelden
|
||
kaldırılmıştır — hücreler kanvasta çocuk düğüm olarak doldurulur. Veri bağlanabilir tablo
|
||
istiyorsan `Grid` (data) ya da `DataGridView` (platform) kullan.
|
||
|
||
**`Spacer`** (`ui` grubunda listelenir) — dikey boşluk: `height` (`24`).
|
||
|
||
### 10.7 `platform` bileşenleri — prop sözleşmesi
|
||
|
||
Dokuzu da aynı üç prop'u alır; başka prop'ları **yoktur** (görünümün tüm davranışı gömülen
|
||
ListForm ekranının kendi tanımından gelir):
|
||
|
||
| Prop | Varsayılan | Anlam |
|
||
| --- | --- | --- |
|
||
| `listFormCode` | `""` | **Zorunlu.** Gömülecek ekranın kodu |
|
||
| `height` | `"520px"` (`ChartView`: `"420px"`) | Kapsayıcı yüksekliği |
|
||
| `className` | `""` | |
|
||
|
||
`ListView` · `DataGridView` · `TreeView` · `GanttView` · `TodoBoard` · `CardView` ·
|
||
`SchedulerView` · `PivotView` · `ChartView`. Bileşen, kullanıcının o ekranda yetkisi yoksa
|
||
ekranın kendi yetki hatasını gösterir; ayrıca gizlemek istiyorsan `designerPermission` yaz.
|
||
Gömülen görünüm, hedef ekranın `LayoutJson`'ında açık olmalıdır.
|
||
|
||
### 10.8 `html` elemanları — prop sözleşmesi
|
||
|
||
| Eleman | Prop'lar | Olaylar |
|
||
| --- | --- | --- |
|
||
| `div` (çocuk kabul eder) | `children`, `className`, `style` | `onClick`, `onMouseEnter`, `onMouseLeave` |
|
||
| `p` · `span` | `children`, `className` | `onClick` |
|
||
| `h1`–`h5` | `children`, `className` — başlıklar hazır Tailwind sınıfıyla düşer (`h1`: `text-4xl font-bold` … `h5`: `text-lg font-semibold`); Tailwind reset'i yüzünden sınıfı silersen başlık paragraf boyutuna iner | `onClick` |
|
||
| `img` | `src` (yeni düşen eleman gömülü SVG yer tutucusuyla gelir; herhangi bir URL/data-URI yazılabilir), `alt`, `width`, `height`, `className` (`max-w-full rounded-md`) | `onClick`, `onLoad` |
|
||
|
||
`input`/`button`/`textarea`/`select`/`checkbox` etiketleri kutuda yoktur — `ui` karşılıklarını
|
||
kullan (§10.1).
|
||
|
||
### 10.9 `data` ve `ui` bileşenleri — Property Panel sözleşmeleri
|
||
|
||
Kaynak: `generated/componentProps.json` + `catalog.ts` düzeltmeleri. Her tabloda yalnızca
|
||
karar gerektiren prop'lar listelenir; `className`, `children`, `style` her bileşende vardır ve
|
||
tekrarlanmaz. `(z)` = zorunlu.
|
||
|
||
**Veri bileşenleri** (koleksiyon prop'u §10.3'e göre statik değer ya da data source binding'i
|
||
alır):
|
||
|
||
| Bileşen | Koleksiyon | Diğer prop'lar (varsayılan) |
|
||
| --- | --- | --- |
|
||
| `Select` | `options[]` (`{label, value}`) | `size` (`sm/md/lg`), `componentAs` (`''` \| `ReactSelect` \| `CreatableSelect` \| `AsyncSelect`), `value`, `isDisabled` (`false`), `isMulti` (`false`), `isClearable` (`false`), `isSearchable` (`true`) — tasarımcı `disabled/multiple/clearable/searchable` adlarını react-select karşılıklarına çevirir |
|
||
| `AutoComplete` | `options[]` | `value`, `defaultValue`, `placeholder`, `disabled` (`false`), `invalid` (`false`), `size`, `debounce`, `minChars` (`1`), `clearable` (`true`), `noOptionsText`, `loadingText`, `name` |
|
||
| `Dropdown` | `items[]` (`{eventKey, children, to}`) | `title` (`'Dropdown'`), `trigger` (`click` \| `hover` \| `context`), `placement` (`bottom-start`; 10 değerli liste), `disabled`, `activeKey`, `menuClass`, `menuStyle` |
|
||
| `Menu` | `items[]` (`{eventKey, icon, children/label}`) | `menuItemHeight` (`30`), `sideCollapsed` (`false`), `variant` (`light` \| `dark` \| `themed` \| `transparent`), `defaultActiveKeys[]`, `defaultExpandedKeys[]` |
|
||
| `Pagination` | `items[]` | `currentPage` (`1`), `pageSize` (`1`), `total` (`5`), `displayTotal` (`false`) |
|
||
| `Radio.Group` | `items[]` (`{value, label, disabled}`) | `name` (`'radioGroup'`), `value`, `vertical` (`false`), `disabled`, `readOnly`, `color` |
|
||
| `Tabs` | `items[]` (`{label, value}`) — **her sekme değeri bir çocuk yuvasıdır** (`slot: "tab:<value>"`), içine bileşen bırakılır | `defaultValue`, `value`, `variant` (`underline` \| `pill`) |
|
||
| `Grid` | `items[]` (satır nesneleri; kolonlar binding'den seçilir) | `cols` (`3`), `rows` (`2`), `gap`/`colGap`/`rowGap` (`4`), `responsive` (`true`), `smCols`/`mdCols`/`lgCols`/`xlCols` (`1/2/3/4`), `autoFit` (`false`), `minColWidth` (`'200px'`), `height` (`'auto'`) |
|
||
|
||
**Form/giriş bileşenleri:**
|
||
|
||
| Bileşen | Prop'lar (varsayılan) |
|
||
| --- | --- |
|
||
| `Input` | `type` (`text`; `HTMLInputTypeAttribute` listesi: `text/password/email/number/tel/url/search/date/time/…`), `value`, `placeholder` (`'Metin girin...'`), `textArea` (`false`) + `rows` (`3`), `prefix`/`suffix`, `size`, `disabled`, `invalid`, `readOnly`, `required`, `maxLength`/`minLength`, `pattern`, `autoComplete` (`off`), `autoFocus`, `name`, `unstyle` |
|
||
| `Checkbox` | `checked`, `defaultChecked`, `value`, `name`, `color`, `disabled`, `readOnly` |
|
||
| `Switcher` | `checked`, `defaultChecked`, `checkedContent`/`unCheckedContent`, `color`, `disabled`, `readOnly`, `isLoading` (`false`), `name` |
|
||
| `Radio` | `checked`, `defaultChecked`, `value`, `name`, `color`, `vertical`, `disabled`, `readOnly` — tekil düğme; seçenek grubu için `Radio.Group` |
|
||
| `DatePicker` | `value`/`defaultValue` (ISO string olarak saklanır, render'da `Date`'e çevrilir), `inputFormat`, `closePickerOnChange` (`true`), `defaultOpen` (`false`), `openPickerOnClear` (`false`), `inputtableBlurClose` |
|
||
| `TimeInput` | `value`/`defaultValue`, `format` (`24` \| `12`), `showSeconds` (`false`), `clearable` (`true`), `amLabel`/`pmLabel`, `timeFieldPlaceholder` (`'--'`), `prefix`/`suffix`, `size` (`md`), `disabled`, `invalid`, `name` |
|
||
| `Calendar` · `RangeCalendar` | `value` (`Date` \| `Date[]`), `multipleSelection` · `value` (`[Date, Date]`), `singleDate` (`false`) |
|
||
| `ColorPicker` | `value`/`defaultValue` (`'#6366f1'`), `presets[]`, `showAlpha`, `showInput` (`true`), `showRgb` (`false`), `size` (`md`), `disabled`, `name` |
|
||
| `Chips` | `value`/`defaultValue` (string dizisi; örnek `['Deneme','Deneme2']`), `max` (`0` = sınırsız), `allowDuplicate` (`false`), `separator`, `placeholder`, `size`, `disabled`, `invalid`, `name` |
|
||
| `Slider` | `value`/`defaultValue`, `min` (`0`), `max` (`100`), `step` (`1`), `range` (`false`), `orientation` (`horizontal` \| `vertical`), `marks`, `tooltip` (`false`), `trackSize` (`4`), `handleSize` (`18`), `disabled`, `readOnly`, `name` |
|
||
| `Knob` | `value`/`defaultValue` (`0`), `min`/`max` (`0/100`), `step` (`1`), `size` (`100`), `strokeWidth` (`14`), `valueColor`/`rangeColor`/`textColor`, `valueTemplate` (`'{value}'`), `showValue` (`true`), `readOnly`, `disabled`, `name` |
|
||
| `Rate` | `count` (`5`), `value`/`defaultValue`, `allowHalf` (`false`), `allowClear` (`true`), `color` (`amber`), `size` (`20`), `gap` (`4`), `tooltips[]`, `disabled`, `readOnly` |
|
||
| `Upload` | `accept`, `multiple`, `draggable` (`false`), `uploadLimit`, `showList` (`true`), `tip`, `fileList[]`, `disabled` — dosyanın **gerçek** yüklenmesi `beforeUpload`/`onChange` script'inde `api.post` ile yapılır |
|
||
|
||
**Gösterim/geri bildirim bileşenleri:**
|
||
|
||
| Bileşen | Prop'lar (varsayılan) |
|
||
| --- | --- |
|
||
| `Button` | `variant` (`default` \| `solid` \| `twoTone` \| `plain`), `color`, `size` (`sm`), `shape` (`round` \| `circle` \| `none`), `icon`, `block` (`false`), `active` (`false`), `loading` (`false`), `disabled` |
|
||
| `Card` (çocuk kabul eder) | `header`/`headerExtra`/`footer`, `headerBorder`/`footerBorder` (`true`), `bordered`, `clickable` (`false`), `bodyClass`/`headerClass`/`footerClass` |
|
||
| `Avatar` | `src`/`srcSet`, `icon`, `alt`, `size` (`md`), `shape` (`circle`; `round` \| `circle` \| `square`) |
|
||
| `Badge` | `content`, `maxCount` (`99`), `innerClass`, `badgeStyle` |
|
||
| `Tag` | `children`, `prefix`/`suffix` (+ `prefixClass`/`suffixClass`), `title` |
|
||
| `Progress` | `variant` (`line` \| `circle`), `percent` (`0`), `color`, `showInfo` (`true`), `customInfo`, `strokeWidth` (`6`), `strokeLinecap` (`round` \| `square`), `width` (`120`; circle), `gapDegree`/`gapPosition` (circle) |
|
||
| `Skeleton` | `variant` (`block` \| `circle`), `animation` (`true`), `width`/`height`, `asElement` |
|
||
| `Spinner` | `size` (`20`), `color`, `isSpining` (`true`), `enableTheme` (`true`), `indicator` |
|
||
| `Notification` | `title`, `type` (`success` \| `warning` \| `danger` \| `info`), `closable` (`false`), `duration` (`3000`), `customIcon`, `width` (`350`) — sayfada sabit kutu olarak durur; olaya bağlı geçici bildirim için script'te `notify()` kullan |
|
||
| `Tooltip` | `title`, `placement` (`top`; 12 değerli `ArrowPlacement` listesi), `isOpen`, `wrapperClass` |
|
||
| `ImageViewer` | `images[]` (`{src, alt, caption}` — yeni düşen bileşen iki örnek görselle gelir), `children` (`'Galeri'` tetikleyici), `defaultIndex` (`0`), `loop` (`true`), `showToolbar`/`showThumbnails` (`true`), `zoomStep` (`0.25`), `minZoom`/`maxZoom` (`0.5/4`), `keyboard` |
|
||
| `Marquee` | `speed` (`100`), `direction` (`left` \| `right` \| `up` \| `down`), `pauseOnHover`/`pauseOnClick` (`false`), `loop` (`0` = sonsuz), `gradient` (`false`), `gradientColor`/`gradientWidth`, `delay` (`0`), `play` (`true`), `autoFill` (`false`) |
|
||
| `ScrollBar` | `direction` (`ltr` \| `rtl`) |
|
||
|
||
### 10.10 Olaylar — bileşen başına `event` yükü
|
||
|
||
JavaScript sekmesinde görünen olaylar ve handler'a gelen tek argümanın (`event`) içeriği.
|
||
Script kapsamındaki her şey (`refs`, `api`, `notify`, `translate`, `checkPermission`) ve
|
||
`Form` yaşam döngüsü olayları `lowcode` §7.8'dedir; buradaki tablo bileşen olaylarının yüküdür.
|
||
|
||
| Bileşen | Olay(lar) | `event` |
|
||
| --- | --- | --- |
|
||
| `Button` | `onClick` | DOM tıklama olayı |
|
||
| `Input` | `onChange` | DOM olayı → değer `event.target.value` |
|
||
| `Checkbox` | `onChange` | `event.checked` |
|
||
| `Select` | `onChange` | Seçilen `{label, value}` nesnesi; temizlenince `null` → `event?.value ?? null` |
|
||
| `AutoComplete` | `onInputChange` · `onSelect` | Yazılan metin · seçilen option nesnesi |
|
||
| `Dropdown` | `onSelect` | Seçilen öğenin `eventKey` değeri |
|
||
| `Menu` | `onSelect` | Seçilen öğenin `eventKey` değeri |
|
||
| `Pagination` | `onChange` | Seçilen sayfa numarası |
|
||
| `Radio.Group` | `onChange` | Seçilen öğenin `value` değeri |
|
||
| `Tabs` | `onChange` | Aktif sekmenin `value` değeri |
|
||
|
||
Bu on bileşen `DESIGNER_PRIMARY_EVENTS` kaydıdır — panel yalnızca bu olayları gösterir.
|
||
Kayıtta olmayan bileşenlerde bütün `function` prop'ları listelenir; işe yarayanlar:
|
||
|
||
| Bileşen | Olaylar |
|
||
| --- | --- |
|
||
| `Switcher` · `ColorPicker` · `Knob` · `Slider` (+`onAfterChange`) · `Rate` (+`onHoverChange`) · `TimeInput` · `DatePicker` · `RangeCalendar` | `onChange` — yeni değer |
|
||
| `Chips` | `onChange`, `onAdd`, `onRemove` |
|
||
| `Upload` | `beforeUpload` (false → dosya reddedilir), `onChange` (dosya listesi), `onFileRemove` |
|
||
| `Card` · `Avatar` · `p` · `span` · `h1`–`h5` | `onClick` |
|
||
| `div` | `onClick`, `onMouseEnter`, `onMouseLeave` |
|
||
| `img` | `onClick`, `onLoad` |
|
||
| `Notification` · `ImageViewer` | `onClose` (`ImageViewer` ayrıca `onIndexChange`) |
|
||
| `Marquee` | `onFinish`, `onCycleComplete` |
|
||
|
||
Sayfa düzeyinde tek yaşam döngüsü kancası vardır: **`lifecycle.onMount`** — sayfa açıldığında
|
||
bir kez çalışır; açılış verisi çekme ve `refs` üzerinden ilk durumu kurma buraya yazılır.
|
||
|
||
> Olay davranışı kurarken önce Script Builder tarifleri (`lowcode` §7.8 tablosu) denenir;
|
||
> serbest kod `custom` tarifiyle eklenir ki sihirbaz açık kalsın.
|
||
|
||
---
|
||
|
||
## 11. Zamanlanmış e-posta (MailQueue modülü)
|
||
|
||
`BackgroundWorker` kaydı `WorkerType: 1` (MailQueueWorker) ise gövde bu modüldür
|
||
(`api/modules/Sozsoft.MailQueue`).
|
||
|
||
### 11.1 Worker `Options` (`MailQueueWorkerOptions`)
|
||
|
||
| Anahtar | Anlam |
|
||
| --- | --- |
|
||
| `MailType` | Şablon tipi etiketi |
|
||
| `MailSubject` | Mail konusu |
|
||
| `MailTemplate` | Razor ile render edilen HTML gövde (`EmailLayout` düzeni içinde) |
|
||
| `TableName` | Maildeki tabloların tarifi (§11.2) |
|
||
|
||
### 11.2 `TableName` biçimi
|
||
|
||
Her tablo `{index:TabloAdi:DosyaTipi:MailEkAdi:Korumalimi:DosyaAciklama}` altılısıdır;
|
||
birden fazlası `};{` ile birleştirilir:
|
||
|
||
```
|
||
{0:MT3_GECIKEN_SIPARIS:IN:Order Delay Notification:0:};{1:MT7_SIPARIS_DURUM:PDF:Durum.pdf:0:BRU,3,1}
|
||
```
|
||
|
||
- `TabloAdi` bir **tablo/view adıdır**; `SELECT * FROM {TabloAdi} WHERE ...` olarak parametreli
|
||
çalıştırılır (parametreler kuyruk satırındaki `TableParameter` alanından gelir).
|
||
- `DosyaTipi` = `IN` ise tablo mail gövdesine gömülür; `PDF` / `XLS` / `TXT` ise ek dosya olur.
|
||
- Sütun başlıkları, sırası, CSS'i ve alt toplamları `BackgroundWorker_MailQueueTableFormat`
|
||
kayıtlarından okunur: `TableName`, `Order`, `ColumnName`, `Caption`, `HeaderCss`, `Css`,
|
||
`FooterCss`, `DataType`, `DataFormat`, `IsHidden`, `IsProtected`, `SubTotal`, `Width`.
|
||
|
||
### 11.3 Kuyruk satırı (`BackgroundWorker_MailQueue`)
|
||
|
||
`TemplateId` (worker), `From`, `To`, `MailParameter`, `TableName`, `TableParameter`,
|
||
`Attachment`, `AttachmentParameter`, `RelatedRecordId`, `SendStatus`, `SendTime`, `AwsMessageId`.
|
||
Gönderim sonuçları `BackgroundWorker_MailQueueEvents` tablosunda izlenir.
|
||
|
||
Kuyruğa satır yazma işi genellikle worker'ın `BeforeSp` prosedüründe ya da ekranın
|
||
`InsertAfterCommand` kancasında yapılır — yani "kayıt onaylanınca mail çıksın" isteği kod
|
||
gerektirmez.
|
||
|
||
---
|
||
|
||
## 12. Saas ve Administration menüleri — platform yetenek kataloğu
|
||
|
||
Bu iki menü, platformun **hazır gelen tüm yeteneklerinin** girişidir. Bir komponent üretirken
|
||
buradaki her ekran üç rolden birindedir:
|
||
|
||
- **Yeniden kullanılacak yetenek** — numaratör, bildirim, zamanlanmış iş, rapor, dosya, yetki,
|
||
dil, ayar. Talebin bu kısmı için yeni artefakt üretilmez; ilgili ekrana kayıt girilir.
|
||
- **Veri kaynağı** — ülke/il/ilçe, para birimi, ölçü birimi, departman, ünvan, şube, kullanıcı,
|
||
rol. Yeni ekranın lookup'ı bu tablolara bağlanır; aynı listeyi tekrar tanımlama.
|
||
- **Referans uygulama** — istenen davranışın bu uygulamada zaten çalışan bir örneği. Aynı JSON'u
|
||
oradan alıp uyarlamak, sıfırdan yazmaktan hem hızlı hem güvenlidir (§12.6).
|
||
|
||
### 12.1 Tablo adlandırma sözleşmesi
|
||
|
||
Platform tablolarının adı `TableNameResolver` tarafından üretilir:
|
||
|
||
```
|
||
{ModülÖnEki}_{H|T|B}_{TableNameEnum} view'ler: V_{aynı ad}
|
||
```
|
||
|
||
| Parça | Değerler |
|
||
| --- | --- |
|
||
| Modül ön eki (`MenuPrefix`) | `Sas` Saas · `Adm` Administration · `Crm` · `Crd` Coordinator · `Scp` SupplyChain · `Mnt` Maintenance · `Str` Store · `Prj` Project · `Hr` · `Mrp` · `Acc` Accounting |
|
||
| Kapsam | `H` host (tüm tenant'lar için ortak) · `T` tenant · `B` şube |
|
||
| Ad | `TableNameEnum` üyesi |
|
||
|
||
Örnek: `Sas_H_Currency` (host — tüm kiracılar aynı para birimlerini görür), `Adm_T_Department`
|
||
(kiracı başına), `V_Sas_H_Order` (view). Özel view'ler
|
||
`TableNameResolver.GetFullSpecialViewName` ile `V_{Önek}_{Prefix}_{Ad}` biçiminde üretilir.
|
||
|
||
> Yeni bir platform tablosu eklenecekse `TableNameEnum` + `TableNameResolver._map` birlikte
|
||
> güncellenir; eşlemesi olmayan ad `KeyNotFoundException` fırlatır. Proje tabloları için
|
||
> `lowcode.instructions.md` §2'deki `{Modul}_T_{Entity}` kuralı geçerlidir.
|
||
|
||
### 12.2 Saas menüsü
|
||
|
||
Kök menü `App.Saas`. Yetki adı her satırda menünün `RequiredPermissionName` değeridir; ListForm
|
||
ekranlarında alt yetkiler `.Create`, `.Update`, `.Delete`, `.Export`, `.Import`, `.Note`
|
||
soneklerini alır.
|
||
|
||
| Ekran | Kod / route | Tablo | Kapsam | Komponent üretirken ne işe yarar |
|
||
| --- | --- | --- | --- | --- |
|
||
| **Tenants** | `AbpTenantManagement.Tenants` | `AbpTenants` | host | Kiracı kaydı, bağlantı dizesi diyaloğu (`TenantsConnectionString`), alt form olarak şubeler. Ekranların `IsTenant` davranışının kaynağı. |
|
||
| **Branches** | `App.Branches` | `Sas_T_Branch` | tenant | Şube listesi. Ekranı `IsBranch = true` yaparsan filtre bu tablodan gelir; `BranchSeed` diyaloğu şube verisini kurar. |
|
||
| **Definitions › AiBot** | `App.Definitions.AiBot` | `Sas_H_AiBot` | host | Yapay zekâ asistanı tanımı (`Name`, `ApiUrl`, `Tenants`); `/admin/ai` bu kayıtları kullanır. |
|
||
| **Definitions › Global Search** | `App.Definitions.GlobalSearch` | `Sas_T_GlobalSearch` | tenant | Üretilen ekranın üst aramada çıkması için kayıt: `System`, `Group`, `Term`, `Weight`, `Url`. |
|
||
| **Definitions › Contact Title** | `App.Definitions.ContactTitle` | `Sas_H_ContactTitle` | host | Ünvan lookup'ı (`Title`, `Abbreviation`). |
|
||
| **Definitions › Currency** | `App.Definitions.Currency` | `Sas_H_Currency` | host | Para birimi + `Rate`. Tutar alanı olan ekranın kur lookup'ı ve `DbQuery` varsayılanı buradan beslenir. |
|
||
| **Definitions › Country Group / Country / City / District** | `App.Definitions.CountryGroup` · `.Country` · `.City` · `.District` | `Sas_H_CountryGroup` · `Sas_H_Country` · `Sas_H_City` · `Sas_H_District` | host | Adres alanlarının hazır cascade zinciri. `Country` ayrıca `PhoneCode`, `PhoneNumberFormat`, `ZipRequired`, `StateRequired`, `TaxLabel` taşır — adres doğrulaması için kullan. |
|
||
| **Definitions › Skill Type / Skill / Skill Level** | `App.Definitions.SkillType` (+ alt kayıtlar) | `Sas_H_SkillType` · `Sas_H_Skill` · `Sas_H_SkillLevel` | host | Yetkinlik ağacı; `SkillType` kendi kendine ebeveyn olan alt form örneğidir. |
|
||
| **Definitions › UoM Category / UoM** | `App.Definitions.UomCategory` | `Sas_H_UomCategory` · `Sas_H_Uom` | host | Ölçü birimi, `Ratio`/`Rounding` — miktar alanı olan ekranlarda birim lookup'ı ve çevrim. |
|
||
| **Definitions › Sequence** | `App.Definitions.Sequence` | `Adm_T_Sequence` | tenant | Belge numarası üretimi (`lowcode.instructions.md` §9.9); alan varsayılanında `CustomValueType: 5` ile bağlanır. |
|
||
| **Public › Home / About / Services / Contact** | `App.Home` · `App.About` · `App.Services` · `App.Contact` — `/admin/public/{ad}/designer` | `Sas_H_Home` · `Sas_H_About` · `Sas_H_Service` · `Sas_H_Contact` | host | Genel siteye açık sayfalar; tasarımcıdan düzenlenir. Public sayfa isteği kod değil bu tasarımcıdır. |
|
||
| **Public › Products / Payment Methods / Installment Options** | `App.Orders.Products` · `.PaymentMethods` · `.InstallmentOptions` | `Sas_H_Product` · `Sas_H_PaymentMethod` · `Sas_H_InstallmentOption` | host | Ürün, ödeme yöntemi (`Commission`), taksit — satış/abonelik ekranlarının lookup kaynağı. |
|
||
| **Public › Sales Orders** | `App.Orders.SalesOrders` | `Sas_H_Order` + `Sas_H_OrderItem` | host | **Onay akışı + alt kalem + toplam + diyalog** birlikte kullanılan tam örnek (§12.6). |
|
||
| **Public › Blog Category / Posts** | `App.BlogManagement.Category` · `.Posts` | `Sas_H_BlogCategory` · `Sas_H_BlogPost` | host | Çok dilli içerik (`ContentTr`/`ContentEn`), slug, yayın durumu, sayaç alanları. |
|
||
| **Public › Demos** | `App.Demos` | `Sas_H_Demo` | host | Siteden gelen demo talepleri — public form → tablo akışının örneği. |
|
||
| **Dev Requests** | `App.DevRequests` | `Sas_H_DevRequest` | host | **Kanban/Todo düzeninin** referansı: `Status`, `Priority`, `SortOrder`, `Tags`, `Assignees`, `SubTasks`, `Timesheets`. |
|
||
| **Setting Definitions** | `App.SettingDefinitions` | `Sas_H_SettingDefinition` | host | Yeni uygulama ayarı: `Code`, `MainGroupKey`/`SubGroupKey`, `DataType`, `SelectOptions`, `DefaultValue`, `Providers`, `RequiredPermissionName`, `IsEncrypted`, `IsVisibleToClients`. Ayarlanabilir olması gereken değeri koda gömme. |
|
||
| **Languages › Language / Language Text** | `App.Languages.Language` · `.LanguageText` | `Sas_H_Language` · `Sas_H_LanguageKey` · `Sas_H_LanguageText` | host | Dil anahtarları. Üretilen her ekranın EN+TR metinleri buraya (ve `LanguagesData.json`'a) yazılır. |
|
||
| **Data Source** | `App.DataSource` | `Sas_H_DataSource` | host | `Code`, `DataSourceType`, `ConnectionString`. **İki tür kayıt bir arada:** elle tanımlanan host/harici bağlantılar ve `Code = tenant adı` olan otomatik tenant bağlantıları (Tenants ekranındaki bağlantı diyaloğu yönetir, elle dokunma). `IsTenant` ekran önce tenant kaydını, yoksa `DataSourceCode`'u kullanır — çözüm kuralı `lowcode` §9.3.3. Bağlantı dizesi koda/JSON'a yazılmaz. |
|
||
| **Notifications › Types / Rules / Notifications** | `App.Notifications.NotificationTypes` · `.NotificationRules` · `.Notification` | `Sas_H_NotificationType` · `Sas_H_NotificationRule` · `Sas_H_Notification` | host | Olay bazlı bildirim (7 kanal); kural ekranındaki `CreateNotification` diyaloğu ile elle bildirim üretilir. Ayrıntı: §9.11. |
|
||
| **Background Workers › Recurring Jobs / Jobs** | `App.BackgroundWorkers.RecurringJobs` · `.Jobs` | `Sas_H_BackgroundWorker` · `Sas_H_BackgroundWorker_JobFlow` | host | Cron'lu işler ve çalıştırma geçmişi (`ExecutionDate`, `Duration`, `Status`, `FailureReason`, `ExceptionDetails`). Ayrıntı: §9.10 ve bu dosyanın §11'i. |
|
||
| **Menus › Routes / Module / Menu / Manager** | `App.Menus.Routes` · `.Module` · `.Menu` · `.Manager` (`/admin/menuManager`) | `Sas_H_Route` · `Sas_H_Module` · `Sas_H_Menu` | host | Menü ve route veritabanından gelir; üretilen ekranın menü kaydı buradan açılır. `Menu` ekranı ağaç düzeninin referansıdır, `Routes` yalnızca özel React sayfası eklenirken kullanılır. |
|
||
| **Developer Kit › SQL Query Manager** | `App.SqlQueryManager` · `/admin/sqlQueryManager` | — | — | View/procedure/function yazma ve çalıştırma; karar sırasının 2. adımı buradan başlar. |
|
||
| **Developer Kit › Custom Endpoints** | `App.DeveloperKit.CustomEndpoints` | `Sas_H_CustomEndpoint` | tenant | `Name`, `Url`, `Method`, `DataSourceCode`, `Sql`, `ParametersJson`, `PermissionsJson` — parametreli SQL'i yetkili bir HTTP ucuna çevirir. |
|
||
| **Developer Kit › Dynamic Services** | `App.DeveloperKit.DynamicServices` · `/admin/developerkit/dynamic-services` | `Sas_H_DynamicService` | host | Monaco editöründe yazılan, derlenip yayınlanan C# servisi; SQL'in yetmediği iş kuralı için 3. adım. |
|
||
| **Developer Kit › Components** | `App.DeveloperKit.Components` · `/admin/developerkit/components` | `Sas_H_CustomComponent` | host | Custom component listesi ve **Visual Designer** girişi (§10). |
|
||
| **Developer Kit › ListForm** | `App.Listforms.Listform` | `Sas_H_ListForm` · `Sas_H_ListFormField` · `Sas_H_ListFormWorkflow` · `Sas_H_ListFormCustomization` · `Sas_H_ListFormImport` | host | Ekran tanımlarının kendisi. Bu dosyada anlatılan bütün JSON kolonlarının canlı hâli; düzenleyicisi `/admin/listform/edit/{kod}`. |
|
||
| **Developer Kit › Wizard Manager** | menü kodu `App.Listforms.WizardManager` · yetki `App.Listforms.Wizard` · `/admin/listform/wizardManager` | — | host | Wizard seed dosyalarının listesi, düzenlemesi, silinmesi, export/import'u. Sihirbazın kendisi ayrı bir rotadadır: `/admin/listform/wizard`. |
|
||
| **Forum Management** | `App.ForumManagement` · `/admin/forumManagement` | `Sas_T_ForumCategory` · `Sas_T_ForumTopic` · `Sas_T_ForumPost` | tenant | Forum kategori/konu yönetimi; yayın tarafı Administration'daki `/admin/forum`. |
|
||
|
||
> Menü kodu ile yetki adı **her zaman aynı değildir**: Wizard Manager'da kod
|
||
> `App.Listforms.WizardManager`, yetki `App.Listforms.Wizard`'dır; Administration'daki Forum
|
||
> ekranında kod `App.Forum`, yetki `App.ForumManagement.Publish`'tir. Yeni ürettiğin ekranlarda
|
||
> ikisini ayırma — wizard zaten aynı kökü kullanır (`lowcode` §2).
|
||
|
||
### 12.3 Administration menüsü
|
||
|
||
Kök menü `App.Administration`. Bu menünün tabloları `Adm_T_*` — yani **kiracı başına** ayrışır.
|
||
|
||
| Ekran | Kod / route | Tablo | Komponent üretirken ne işe yarar |
|
||
| --- | --- | --- | --- |
|
||
| **Definitions › Sector** | `App.Definitions.Sector` | `Adm_T_Sector` | Sektör lookup'ı. |
|
||
| **Definitions › Department** | `App.Definitions.Department` | `Adm_T_Department` | `ParentId` ile **ağaç (TreeList) düzeninin** referansı; personel/onay ekranlarının departman lookup'ı. |
|
||
| **Definitions › Job Position** | `App.Definitions.JobPosition` | `Adm_T_JobPosition` | Ünvan ağacı (`ParentId` + `DepartmentId`) — departmana bağlı cascade örneği. |
|
||
| **Definitions › Org Chart** | `App.Definitions.OrgChart` · `/admin/organization` | `Adm_T_Department` | Departman/ünvan verisinin organizasyon şeması görünümü. |
|
||
| **Licence** | `App.Licence` · `/admin/form/App.Licence` | `AbpTenants` + `V_Sas_H_OrderItem_ByTenantId` | **`ListFormType = Form`** (listesiz, tek kayıtlık ekran) + alt kalem listesi. "Tek kayıtlık kart ekran" isteğinin karşılığı budur. |
|
||
| **Dev Request** | `App.DevRequest` | `Sas_H_DevRequest` | Kiracı tarafındaki talep ekranı (Saas'taki listenin kullanıcı yüzü). |
|
||
| **Agenda** | `App.Agenda` | `Adm_T_Agenda` | **Takvim (Scheduler) düzeninin** referansı: `StartDate`, `EndDate`, `AllDay`, `RecurrenceRule`, `RecurrenceException`. Tekrarlayan randevu isteği kod gerektirmez. |
|
||
| **Settings** | `App.Setting` · `/admin/settings` | — | `SettingDefinition` kayıtlarından üretilen ayar ekranı; değerler burada girilir. |
|
||
| **Intranet › Announcement (+Like/Comment)** | `App.Intranet.Announcement` | `Adm_T_Announcement` · `Adm_T_AnnouncementLike` · `Adm_T_AnnouncementComment` | Duyuru + beğeni + yorum: **ana kayıt / alt etkileşim** kalıbının hazır örneği. |
|
||
| **Intranet › Survey (+Question/Option/Response/Answer)** | `App.Intranet.Survey` | `Adm_T_Survey` · `Adm_T_SurveyQuestion` · `Adm_T_SurveyQuestionOption` · `Adm_T_SurveyResponse` · `Adm_T_SurveyAnswer` | Anket motoru; soru–seçenek–yanıt zinciri **iki seviyeli alt form** ihtiyacının referansıdır. |
|
||
| **Intranet › Social Post (+Comment/Like)** | `App.Intranet.SocialPost` | `Adm_T_SocialPost` · `Adm_T_SocialComment` · `Adm_T_SocialLike` (+ `SocialPollOption`, `SocialMedia`, `SocialLocation`) | Kurum içi akış; `IsLiked`, `IsOwnPost` gibi hesaplanmış kolonların view içinde üretilmesine örnek. |
|
||
| **Intranet › Event Type / Category / Event (+Like/Comment)** | `App.Intranet.Events.*` | `Adm_T_EventType` · `Adm_T_EventCategory` · `Adm_T_Event` · `Adm_T_EventPhoto` · `Adm_T_EventLike` · `Adm_T_EventComment` | Etkinlik yönetimi; foto ve katılımcı sayacı olan kayıt kalıbı. |
|
||
| **Restrictions › Work Hour** | `App.Restrictions.WorkHour` | `Adm_T_WorkHour` | Gün bazlı çalışma saati (`Monday`…`Sunday`, `StartTime`, `EndTime`); kullanıcıya `AbpUsers.WorkHour` ile bağlanır. "Sadece mesai saatinde girilebilsin" burada çözülür. |
|
||
| **Restrictions › IP Restrictions** | `App.Restrictions.IpRestrictions` | `Adm_T_IpRestriction` | `ResourceType` + `ResourceId` + `IP` — kullanıcı/rol bazlı IP kısıtı. |
|
||
| **Identity › Permission Groups / Permissions** | `Abp.Identity.PermissionGroups` · `Abp.Identity.Permissions` | `AbpPermissionGroups` · `AbpPermissions` | Yetki ağacı (tree düzeni). Yeni ekranın yetkileri burada görünür; `Modules` kolonu yetkiyi modüllere bağlar (pipe ile çoklu). |
|
||
| **Identity › Claim Type** | `App.IdentityManagement.ClaimType` | `AbpClaimTypes` | Kullanıcıya ek alan (claim) tanımı: `ValueType`, `Regex`, `Required`, `IsStatic`. |
|
||
| **Identity › Roles** | `AbpIdentity.Roles` | `AbpRoles` | Rol yönetimi + `RolesPermission` diyaloğu; yeni ekranın yetkisi role buradan verilir. |
|
||
| **Identity › Users** | `AbpIdentity.Users` | `AbpUsers` | Kullanıcı yönetimi + `UsersPermission` diyaloğu, **KPI widget'ları** ve `list-form-dynamic-api/user-*` ile devredilen yazma. Kullanıcı `WorkHour`, `DepartmentId`, `JobPositionId` alanlarını taşır. |
|
||
| **Identity › Organization Units** | `Abp.Identity.OrganizationUnits` · `/admin/ous` | ABP OU tabloları | Birim ağacı. Ekranı `IsOrganizationUnit = true` yaparsan veri bu ağaca göre süzülür; bildirim alıcısı da OU olabilir. |
|
||
| **Identity › Audit Logs** | `App.IdentityManagement.AuditLogs` | `AbpAuditLogs` | İstek denetim kaydı + `AuditLogDetail` diyaloğu. "Kim ne zaman ne yaptı" isteği yeni tablo gerektirmez. |
|
||
| **Identity › Sessions** | `App.IdentityManagement.Sessions` | `AbpSessions` | Açık oturumlar; `UiEvalService.ApiKickUser` ile oturum düşürme (§9.13). |
|
||
| **Reports › Categories / Templates** | `App.Reports.Categories` · `App.Reports.ReportTemplates` | `Adm_T_ReportCategory` · `Adm_T_ReportTemplate` | Kendi düzeni olan çıktılar (fatura, teklif); ekrana `CommandColumnJson` butonuyla bağlanır (§9.12). |
|
||
| **Videoroom** | `App.Videoroom` · `/admin/videoroom/dashboard` | `Adm_T_Videoroom` · `Adm_T_VideoroomParticipant` · `Adm_T_VideoroomAttandance` · `Adm_T_VideoroomChat` | Görüntülü oda, katılım ve sohbet kaydı. |
|
||
| **Files** | `App.Files` · `/admin/files` | — | Dosya yöneticisi. Ekranın dosya alanı için ayrı depolama kurma; dosya/görsel editörleri bu altyapıyı kullanır. |
|
||
| **Forum** | menü kodu `App.Forum` · yetki `App.ForumManagement.Publish` · `/admin/forum` | `Sas_T_Forum*` | Forumun kullanıcı tarafı. |
|
||
|
||
Menüde görünmeyen ama route'u olan ekranlar: `/admin/dashboard`, `/admin/ai`,
|
||
`/admin/activityLog`, `/admin/changeLog`, `/admin/profile/{general,password,notification-settings}`,
|
||
`/admin/users/detail/:userId` (yetki `AbpIdentity.Users.Update`), `/admin/videoroom/list` ve
|
||
`/admin/videoroom/room/:id`, `/admin/reports/*`, `/admin/listform/{wizard,wizardManager}`,
|
||
`/admin/listform/edit/:listFormCode` ve dinamik ekran rotaları.
|
||
|
||
**Dinamik ekran rotaları** — üretilen her ListForm ekranı bunları kullanır, ayrıca route kaydı
|
||
açılmaz:
|
||
|
||
| Route | Bileşen | Ne açar |
|
||
| --- | --- | --- |
|
||
| `/admin/list/:listFormCode` | `views/list/List` | Liste (grid/card/pivot/tree/gantt/scheduler/todo — `LayoutJson`'a göre) |
|
||
| `/admin/form/:listFormCode` | `views/form/FormNew` | Yeni kayıt formu |
|
||
| `/admin/form/:listFormCode/:id` | `views/form/FormView` | Tek kayıt görüntüleme (`AllowDetail` bunu açar) |
|
||
| `/admin/form/:listFormCode/:id/edit` | `views/form/FormEdit` | Tek kayıt düzenleme |
|
||
| `/admin/chart/:listFormCode` | `views/list/Chart` | Yalnız grafik ekranı |
|
||
|
||
`/admin/pivot/...` diye bir route **yoktur**; pivot, liste ekranındaki bir görünümdür.
|
||
|
||
### 12.4 ListForm olmayan (özel React) ekranlar
|
||
|
||
Bu ekranlar `Sas_H_Route` kayıtlarıyla yönetilir (seed: `MenusData.json` → `Routes`). Yenisini
|
||
eklemek **kod yazmak demektir** — karar sırasının son adımıdır.
|
||
|
||
Bir route kaydının alanları: `key`, `path`, `componentType`, `componentPath` (`@/views/...`),
|
||
`routeType`, `authority[]`.
|
||
|
||
| `routeType` | Anlam |
|
||
| --- | --- |
|
||
| `public` | Oturum gerekmez — genel siteye açık sayfalar |
|
||
| `authenticated` | Kimlik akışı sayfaları (giriş, kayıt, parola, doğrulama) |
|
||
| `protected` | Oturum zorunlu; `authority` doluysa ayrıca yetki kontrolü yapılır |
|
||
|
||
`authority: []` **yetki kontrolü yok** demektir; ekranın kendi yetkisi varsa kontrol
|
||
bileşenin/ListForm'un içindedir. Custom component route'ları da böyle üretilir — bu yüzden
|
||
görünürlük `checkPermission` ile bileşen içinde kurulur (`lowcode` §7.5).
|
||
|
||
| Route | Bileşen | Yetki |
|
||
| --- | --- | --- |
|
||
| `/admin/menuManager` | `views/menu/MenuManager` | `App.Menus.Manager` |
|
||
| `/admin/listform/wizard` | `listForm/wizard/Wizard` | `App.Listforms.Wizard` |
|
||
| `/admin/listform/wizardManager` | `listForm/wizard/WizardFileManager` | `App.Listforms.Wizard` |
|
||
| `/admin/listform/edit/:listFormCode` | `listForm/edit/FormEdit` | `[]` — yetki ListForm tarafında |
|
||
| `/admin/sqlQueryManager` | `developerKit/SqlQueryManager` | `App.SqlQueryManager` |
|
||
| `/admin/developerkit/dynamic-services{,/new,/edit/:id}` | `DynamicServiceManager` · `DynamicServiceEditor` | `App.DeveloperKit.DynamicServices` |
|
||
| `/admin/developerkit/components{,/edit/:id}` | `ComponentManagerPage` · `ComponentCodeLayout` | `App.DeveloperKit.Components` |
|
||
| `/admin/reports/:report/{view,design}/:id?/:listFormCode?` | `DevexpressReportViewer` · `DevexpressReportDesigner` | — |
|
||
| `/admin/public/{home,about,services,contact}/designer` | ilgili public sayfa (tasarım modu) | `App.Home` · `App.About` · `App.Services` · `App.Contact` |
|
||
| `/admin/settings` | `settings/Settings` | `App.Setting` |
|
||
| `/admin/files` | `admin/files/FileManager` | `App.Files` |
|
||
| `/admin/ous` · `/admin/organization` | `organization-unit/OrganizationUnits` · `hr/OrgChart` | `Abp.Identity.OrganizationUnits` · `App.Definitions.Department` |
|
||
| `/admin/forum` · `/admin/forumManagement` | `forum/Forum` · `forum/Management` | `App.ForumManagement.Publish` · `App.ForumManagement` |
|
||
| `/admin/videoroom/{dashboard,list,room/:id}` | `admin/videoroom/{Dashboard,RoomList,RoomDetail}` | `App.Videoroom{,.List,.Detail}` |
|
||
| `/admin/ai` | `ai/Assistant` | `App.Definitions.AiBot.Asistant` |
|
||
| `/admin/dashboard` · `/admin/activityLog` · `/admin/changeLog` · `/admin/profile/*` | `Dashboard` · `admin/activityLog/ActivityLog` · `version/ChangeLog` · `admin/profile/Profile` | `[]` |
|
||
| `/admin/users/detail/:userId` | `admin/user-management/Details` | `AbpIdentity.Users.Update` |
|
||
|
||
**Oturum gerektirmeyen sayfalar** (`routeType: public`) — genel site. İçerikleri kod değil,
|
||
Saas › Public altındaki tasarımcı ekranlarından ve tablolardan gelir; bir "tanıtım sayfası"
|
||
isteğinde yeni React sayfası yazma, bunları kullan:
|
||
|
||
| Route | Bileşen | Veri |
|
||
| --- | --- | --- |
|
||
| `/home` · `/about` · `/services` · `/contact` | `views/public/{Home,About,Services,Contact}` | `Sas_H_{Home,About,Service,Contact}` · tasarımcı: `/admin/public/{ad}/designer` |
|
||
| `/products` · `/checkout` · `/payment` · `/success` | `views/public/{Products,Checkout,Payment,Success}` | `Sas_H_Product` · `Sas_H_PaymentMethod` · `Sas_H_InstallmentOption` · `Sas_H_Order` |
|
||
| `/blog` · `/blog/:id` | `views/public/{Blog,BlogDetail}` | `Sas_H_BlogPost` · `Sas_H_BlogCategory` |
|
||
| `/demo` | `views/public/Demo` | `Sas_H_Demo` |
|
||
| `/access-denied` | `views/AccessDenied` | — |
|
||
|
||
**Kimlik akışı** (`routeType: authenticated`): `/login`, `/register`, `/forgot-password`,
|
||
`/reset-password`, `/confirm`, `/confirm/:userId/:token`, `/extend-login` →
|
||
`views/auth/*`. Bunlara dokunma; parola ve doğrulama akışları ABP tarafındadır.
|
||
|
||
### 12.5 Talep → hangi menü
|
||
|
||
§0'daki katman taraması bu tabloyla eşleşir; "kod yazmamız gerekir" demeden önce buraya bak.
|
||
|
||
| Talepte geçen | Menü / ekran | Ne yapılır |
|
||
| --- | --- | --- |
|
||
| "numara otomatik gelsin" | Saas › Definitions › Sequence | Kayıt aç, alan varsayılanına `CustomValueType: 5` |
|
||
| "her gece / saat başı çalışsın" | Saas › Background Workers | `WorkerType: 2` + `BeforeSp`; prosedür `sql/object/` altına |
|
||
| "bilgilendirme gitsin" | Saas › Notifications (+ MailQueue §11) | Tür + kural; e-posta ise MailQueue |
|
||
| "onaya düşsün" | `WorkflowJson` + `ListFormWorkflow` (örnek: Sales Orders) | Onay düğümleri; `Inform` düğümü e-posta gönderir |
|
||
| "çıktısı alınsın / fatura basılsın" | Administration › Reports | Hazır `DynamicGrid` ya da `ReportTemplate` |
|
||
| "dosya eklensin" | Administration › Files | Dosya/görsel editörü; ayrı depolama kurma |
|
||
| "başka veritabanından gelsin" | Saas › Data Source | Yeni DataSource + ekranın `DataSourceCode` alanı |
|
||
| "ayarlanabilir olsun" | Saas › Setting Definitions | Tanım aç, değeri `/admin/settings`'ten yönet |
|
||
| "İngilizcesi de olsun" | Saas › Languages | Dil anahtarı + `LanguagesData.json` |
|
||
| "aramada çıksın" | Saas › Definitions › Global Search | `System`/`Group`/`Term`/`Weight`/`Url` kaydı |
|
||
| "sadece şu rol görsün" | Administration › Identity › Roles / Permissions | Yetki kodu + ekranın `PermissionJson`'ı |
|
||
| "şube bazlı olsun" | Saas › Branches | `IsBranch = true` |
|
||
| "birim ağacına göre süzülsün" | Administration › Identity › Organization Units | `IsOrganizationUnit = true` |
|
||
| "mesai dışında girilemesin" / "sadece ofis IP'si" | Administration › Restrictions | Work Hour · IP Restriction kaydı |
|
||
| "kim değiştirmiş görelim" | Administration › Identity › Audit Logs | Hazır ekran; kayıt notu için `ShowNote` |
|
||
| "menüye eklensin" | Saas › Menus › Manager | Menü kaydı + yetki + route eşlemesi |
|
||
| "ülke/il/ilçe, para birimi, birim, departman, ünvan" | Saas / Administration › Definitions | Var olan tabloya lookup bağla, yenisini üretme |
|
||
| "yapay zekâ cevaplasın" | Saas › Definitions › AiBot | Bot tanımı; `/admin/ai` bu tanımı kullanır |
|
||
|
||
### 12.6 Canlı referans uygulamalar
|
||
|
||
İstenen davranışın bu uygulamada çalışan örneği. Tanımlar
|
||
`api/src/Sozsoft.Platform.DbMigrator/Migrations/ListFormSeeder_{Saas,Administration}.cs`
|
||
içinde ilgili `#region` altındadır.
|
||
|
||
| İhtiyaç | Bak |
|
||
| --- | --- |
|
||
| Ağaç (TreeList) | `Menu`, `Permission`, `Department`, `JobPosition` |
|
||
| Kanban / Todo | `DevRequests` (`TodoOptionJson` + `SortOrder`, `Priority`, `Tags`) |
|
||
| Takvim (Scheduler) | `Agenda` (`SchedulerOptionJson` + `RecurrenceRule`) |
|
||
| Tek kayıtlık form ekranı | `Licence` (`ListFormType = Form` + alt kalem listesi) |
|
||
| Onay akışı | `Sales Orders` — `WorkflowJson` (`ApprovalUserFieldName`, `ApprovalStatusFieldName`, `ApprovalDateFieldName`, `ApprovalDescriptionFieldName`) + `ListFormWorkflow` düğümleri (Start → Approval → End/End) |
|
||
| Alt form (master-detail) | `Tenant → Branches`, `Sales Orders → Sales Order Item`, `Survey → Question → Option` |
|
||
| KPI widget | `User` — `WidgetsJson`; sorgu `Title`, `Value`, `Color`, `SubTitle`, `Icon` kolonlarını döndürür |
|
||
| Toolbar'dan diyalog açma | `Tenant` (`TenantsConnectionString`), `Role` (`RolesPermission`), `User` (`UsersPermission`), `Audit Logs` (`AuditLogDetail`), `Notification Rule` (`CreateNotification`), `Branches` (`BranchSeed`), `Sales Orders` (`CreateTenantFromOrderDialog`) |
|
||
| Yazmayı servise devretme | `Tenant`, `Role`, `User` — `*ServiceAddress = "list-form-dynamic-api/{tenant\|role\|user}-{insert\|update}"` |
|
||
| Toplam satırı | `Sales Order Item`, `Licence Item` (`TotalSummaryJson`) |
|
||
| View üzerinden okuma | `Background Worker Jobs`, `Licence Item` (`SelectCommandType = View`) |
|
||
| Cascade lookup | `City` → `District` (ülke/il/ilçe zinciri) |
|
||
| Alan varsayılanı ve soft delete | `Tenant` (`FormFieldsDefaultValueJson`, `DeleteFieldsDefaultValueJson`) |
|
||
|
||
### 12.7 Uyarılar
|
||
|
||
- **Bu ekranların seeder'ı idempotenttir:** `ListFormCode` zaten varsa kayıt **güncellenmez**.
|
||
Hazır bir ekranın davranışını değiştirmek gerekiyorsa seeder'ı düzenlemek yetmez; değişikliği
|
||
`sql/execute/{Ad}.sql` altında var olan kaydı güncelleyen bir prosedürle taşı.
|
||
- **Host tablosuna kiracı verisi yazma.** `Sas_H_*` tabloları bütün kiracılar için ortaktır;
|
||
kiracıya özel veri `*_T_*` tablosuna gider. Ekranın `IsTenant`/`IsBranch` bayrakları ile
|
||
tablonun kapsam harfi tutarlı olmalıdır.
|
||
- **Yetki adı menüden gelir.** Ekranın `PermissionJson`'ındaki adlarla menünün
|
||
`RequiredPermissionName` değeri aynı sözleşmeyi göstermelidir; farklıysa kullanıcı menüyü görür,
|
||
ekranı göremez.
|
||
- **Platformun hazır tablolarına doğrudan yazan ekran üretme.** `AbpUsers`, `AbpRoles`,
|
||
`AbpTenants` yazma işi `list-form-dynamic-api` uçlarındadır; ham SQL ile yazmak parola
|
||
hash'ini, yetki önbelleğini ve kiracı kurulumunu atlar.
|
||
|
||
---
|
||
|
||
## 13. Bu dosyanın kapsamadıkları
|
||
|
||
| Konu | Nerede |
|
||
| --- | --- |
|
||
| Karar sırası, üretim protokolü, seed sözleşmesi | `lowcode.instructions.md` §0–§2 |
|
||
| Wizard seed dosyasının alanları | `lowcode.instructions.md` §4 |
|
||
| `EditorScript` tarifleri ve runtime API | `lowcode.instructions.md` §5 |
|
||
| `EditorOptions` sözlüğü ve preset'ler | `lowcode.instructions.md` §6 |
|
||
| Visual Designer doküman şeması ve event script'leri | `lowcode.instructions.md` §7 |
|
||
| SQL nesneleri, CRUD/Custom Endpoint, Dynamic Service | `lowcode.instructions.md` §8–§9 |
|
||
| Sequence, zamanlanmış iş, bildirim, rapor ekranları | `lowcode.instructions.md` §9.9–§9.14 |
|
||
| `api/` kod standardı | `dotnet.instructions.md` |
|
||
|
||
DevExtreme'in burada listelenmeyen bir seçeneğini kullanman gerekiyorsa, **nereye yazdığın
|
||
belirleyicidir**:
|
||
|
||
| Nereye | Bilinmeyen anahtara ne olur |
|
||
| --- | --- |
|
||
| Ekran seviyesindeki `*Json` kolonları (§2–§8) | **Düşer.** `GridOptionsDto` ham metni `[JsonIgnore]` ile gizler, istemciye yalnızca tipli DTO gider. Kalıcı olarak gerekiyorsa önce ilgili DTO'ya alan eklenir, sonra bu dosya güncellenir |
|
||
| Alan seviyesindeki `ListFormField.EditorOptions` (§9.8) | **Geçer.** Ham metin olarak istemciye iner ve editöre olduğu gibi verilir; sözlükte olmayan anahtar Options Builder'ın "Sözlük dışı ayarlar" bölümünden de yazılabilir (`lowcode` §6.1) |
|
||
| `CustomJsSourcesJson` / `CustomStyleSourcesJson` (§5.5) | Geçer — ama son çaredir, denetlenmez |
|
||
|
||
Yani "DevExtreme'de var, platformda yok" durumunda önce §9.8'e (editör seçeneği mi?) bak; ekran
|
||
seviyesindeki bir seçenekse DTO'ya eklenmeden çalışmayacağını bilerek planla.
|