diff --git a/.github/instructions/lowcode.instructions.md b/.github/instructions/lowcode.instructions.md index 29518dec..07cff7fe 100644 --- a/.github/instructions/lowcode.instructions.md +++ b/.github/instructions/lowcode.instructions.md @@ -370,6 +370,7 @@ dörtlüyle üretilir (§9.8), görseldeki görünüm `DefaultLayout` olur. | Renk kutucuğu | `dxColorBox` | | | Kalın/italik araç çubuklu alan | `dxHtmlEditor` | `toolbar.items` | | Kaydırıcı | `dxSlider` / `dxRangeSlider` | `min`, `max` | +| Yıldızlı puan (1–5) | `dxRating`, kolon `int` | `count`, `allowClear` | | Fotoğraf / görsel alanı (seçilen, çekilen ya da başka kayıttan kopyalanan) | `dxImageUpload`, kolon `nvarchar(MAX)` (base64); salt okunur gösterilecekse `EditorOptions: {"readOnly": true}` — `dxImageViewer` değil | `accept`, `maxFileSize`, `capture` | | Gri, tıklanamaz alan | ilgili editör + `EditorOptions: {"readOnly": true}` | | | Kırmızı yıldızlı etiket | `IsRequired: true` | | @@ -1072,12 +1073,12 @@ yazılır: | 25 | Xml | `xml` | | 27 | DateTimeOffset | `datetimeoffset` | -**Editör tipleri (`EditorType2`)** — 21 tip, alana **metin** olarak yazılır. DevExtreme'den +**Editör tipleri (`EditorType2`)** — 22 tip, alana **metin** olarak yazılır. DevExtreme'den gelenler: `dxAutocomplete`, `dxCalendar`, `dxCheckBox`, `dxColorBox`, `dxDateBox`, `dxDateRangeBox`, `dxDropDownBox`, `dxHtmlEditor`, `dxLookup`, `dxNumberBox`, `dxRadioGroup`, `dxRangeSlider`, `dxSelectBox`, `dxSlider`, `dxSwitch`, `dxTagBox`, `dxTextArea`, `dxTextBox`. Platformun kendi editörleri (`PlatformEditorTypes`): `dxGridBox`, `dxImageViewer`, -`dxImageUpload` (+ `dxTagBox` platform tarafında da özel işlenir). +`dxImageUpload`, `dxRating` (+ `dxTagBox` platform tarafında da özel işlenir). > **Tuzak:** `PlatformConsts.EditorTypes.dxLookup` sabiti bozuk bir metin taşır > (`"dxHtmlEdidxLookuptor"`). Hiçbir yerde kullanılmadığı için etkisi yoktur, ama C# seeder @@ -1412,6 +1413,7 @@ anahtarları listeler; ortak anahtarlar (§4.3.3) her editörde geçerlidir. | `dxColorBox` | Renk | String (16) | `editAlphaChannel`, `keyStep` | | `dxSlider` | Tek değerli kaydırıcı | Sayı | `min`, `max`, `tooltip.showMode` | | `dxRangeSlider` | Aralık kaydırıcı | Sayı | `min`, `max`, `showRange` | +| `dxRating` | Yıldızlı puan (platform). Tıklanan yıldızın sırası (1..`count`) tam sayı olarak kaydedilir; seçili yıldıza yeniden tıklamak değeri boşaltır (`allowClear: false` kapatır). Liste/kart hücresinde yıldız olarak çizilir; yıldız şablonu olmayan görünümde (Scheduler) sayı kutusudur | Int32 (11) | `count` (varsayılan 5), `allowClear` | | `dxHtmlEditor` | Zengin metin | String (16) | `toolbar.items`, `toolbar.multiline`, `valueType` (`html`/`markdown`), `mediaResizing.enabled`, `imageUpload.tabs`, `imageUpload.uploadUrl`, `imageUpload.fileUploadMode`, `tableResizing.enabled`, `tableContextMenu.enabled`. Boş `editorOptions` da tam araç çubuğu, dosyadan/URL'den resim, resim boyutlandırma ve tablo araçlarıyla gelir (`ui/src/views/shared/htmlEditorOptions.ts`); yazılan değer varsayılanın üstüne tek seviye birleştirilir, yalnızca farkı yaz. | | `dxImageUpload` | Görsel yükleme (platform); görsel tutan her kolonun editörü. `accept` belge türlerini de içerirse (`application/pdf,.doc,.docx` — CV, imzalı form) görsel olmayan `data:` değeri listede ve formda belge ikonuyla çizilir, tıklanınca blob olarak yeni sekmede açılır (`imageHoverPreview.thumbnailSource`). `uploadUrl` yoksa dosya **base64** metin olarak kolona yazılır → kolon `nvarchar(MAX)`; sınırlı boylu kolonla deploy reddedilir. `uploadUrl` varsa kolona dönen adres yazılır | String (16) | `uploadUrl`\*, `accept`\*, `capture`\*, `multiple`\*, `maxFileSize`\*, `width`\*, `height`\* | | `dxImageViewer` | Görsel gösterimi (platform), yükleme yapmaz. Tablo kolonuna bağlı alanda kullanılmaz — görsel kolonu `dxImageUpload`'dır, deploy `dxImageViewer`'ı reddeder | String (16) | `width`, `height` | @@ -1536,7 +1538,7 @@ editör yetenekleri ortak koddan gelir; bir tarafa yeni yetenek ortak yardımcı | Buton `onClick` (fonksiyon metni, `@SCAN_BARCODE`) ve bağlamı | `resolveEditorButtons` + `withButtonContext` | | Cascade temizleme/kilit | `list/shared/cascade.ts` | | Grid/Tree `onEditorPreparing` gövdesi | `prepareEditingEditor` (`list/shared/editingFormScripts.ts`) | -| TagBox, GridBox, ImageUpload, ImageViewer | Tek uygulama `form/editors/*`; liste hücresi `list/editors/cellEditors.tsx` adaptörüyle bağlanır | +| TagBox, GridBox, ImageUpload, ImageViewer, Rating | Tek uygulama `form/editors/*`; liste hücresi `list/editors/cellEditors.tsx` adaptörüyle bağlanır | DataGrid/TreeList platform editörlerini `editCellTemplate` ile çizer ve `onEditorPreparing` onlar için çalışmaz; salt-okunur/devre dışı kararı, cascade ve `EditorScript` bu editörlere @@ -1913,7 +1915,8 @@ cevaba yazılmaz. ], "WorkflowDto": { "ApprovalUserFieldName": "", "ApprovalDateFieldName": "", "ApprovalStatusFieldName": "", "ApprovalDescriptionFieldName": "", - "ApprovalIsFilterUserName": false, "ApprovalIsResetWorkflow": false, "Criteria": [] } + "ApprovalIsFilterUserName": false, "ApprovalIsResetWorkflow": false, + "ApprovalIsManualStart": false, "Criteria": [] } } } ``` @@ -2288,6 +2291,7 @@ wizard'ınkinden **küçük** olmalıdır (§0.2). | `ApprovalDescriptionFieldName` | Onay/ret açıklaması | | `ApprovalIsFilterUserName` | Liste yalnızca kullanıcının onayına düşenleri göstersin | | `ApprovalIsResetWorkflow` | Kayıt güncellenince akış başa dönsün | +| `ApprovalIsManualStart` | Yeni kayıt akışı kendiliğinden başlatmasın; kayıt taslak kalır, akış toolbar'daki başlat düğmesiyle başlar. Onaya gönderilmiş başlığa satır eklemeyi engelleyen alt formu olan ekranlarda (talep + satırlar) açılır; kapalıyken Grid/Tree yeni kaydın ardından akışı başlatır | `Criteria` düğüm grafiğidir. `Kind` değerleri: **`Start`**, **`Compare`**, **`Approval`**, **`Inform`**, **`End`**. @@ -2627,7 +2631,7 @@ Builder'ı (§5) açar — çıktıları `EditorOptions`/`EditorScript` string'l **Adım 7 — İş Akışı.** Zorunlu ikili: `ApprovalUserFieldName` + `ApprovalStatusFieldName`; opsiyonel `ApprovalDateFieldName`, `ApprovalDescriptionFieldName`, `ApprovalIsFilterUserName` (liste yalnız sıradaki onaycıya düşsün), `ApprovalIsResetWorkflow` (kayıt değişince akış başa -dönsün). Onay düğümleri (`Criteria`) görsel akış tasarımcısında kurulur ve `ListFormWorkflow` +dönsün), `ApprovalIsManualStart` (yeni kayıt taslak kalsın, akış başlat düğmesiyle başlasın). Onay düğümleri (`Criteria`) görsel akış tasarımcısında kurulur ve `ListFormWorkflow` kayıtlarına gider (§4.7). **Adım 12 — Deploy.** Sol tarafta tüm adımların özeti, sağda üretim log'u. Log, deploy'un seed @@ -2986,7 +2990,7 @@ Dizi elemanları yaprak sayılmaz; `toolbar.items` tek bir `json` alanıdır. | TagBox | `showSelectionControls`\*, `maxDisplayedTags`\*, `showMultiTagOnly`\*, `applyValueMode`\*, `multiline`, `hideSelectedItems` | `dxTagBox` | | GridBox | `columns`\*, `selectionMode`\*, `filterRowVisible`\* | `dxGridBox` | | Görsel | `uploadUrl`\*, `fileFieldName`, `accept`\*, `capture`\*, `multiple`\*, `maxFileSize`\* | `dxImageUpload`, `dxImageViewer` | -| Seçim | `text` (`dxCheckBox`), `switchedOnText`/`switchedOffText` (`dxSwitch`), `layout` (`dxRadioGroup`), `editAlphaChannel`/`keyStep` (`dxColorBox`) | ilgili editör | +| Seçim | `text` (`dxCheckBox`), `switchedOnText`/`switchedOffText` (`dxSwitch`), `layout` (`dxRadioGroup`), `editAlphaChannel`/`keyStep` (`dxColorBox`), `count`/`allowClear` (`dxRating`) | ilgili editör | | Kaydırıcı | `min`, `max`, `step`, `tooltip.enabled`, `tooltip.showMode`, `showRange` | `dxSlider`, `dxRangeSlider` | | HTML | `valueType`, `toolbar.multiline`, `toolbar.items`, `mediaResizing.enabled`, `imageUpload.tabs`, `imageUpload.fileUploadMode`, `imageUpload.uploadUrl`, `tableResizing.enabled`, `tableContextMenu.enabled` | `dxHtmlEditor` | | Liste sütunu | `format` (metin hâli), `encodeHtml`, `buttons` | hepsi — bu üçü **grid sütununu** da etkiler | diff --git a/README.md b/README.md index d3e77077..bb8341c7 100644 --- a/README.md +++ b/README.md @@ -444,7 +444,7 @@ ve atanan kullanıcı alanlarından kurulur. - **Editör tipleri:** `dxTextBox`, `dxTextArea`, `dxNumberBox`, `dxDateBox`, `dxDateRangeBox`, `dxCalendar`, `dxCheckBox`, `dxSwitch`, `dxRadioGroup`, `dxSelectBox`, `dxTagBox`, `dxLookup`, `dxDropDownBox`, `dxGridBox`, `dxAutocomplete`, `dxColorBox`, `dxHtmlEditor`, `dxSlider`, - `dxRangeSlider` — ayrıca görsel yükleme/görüntüleme editörleri. + `dxRangeSlider` — ayrıca görsel yükleme/görüntüleme editörleri ve yıldızlı puan (`dxRating`). - **Lookup kaynakları:** `StaticData`, `Query`, `WebService`; ebeveyn–çocuk (cascade) desteklidir. Cascade liste popup'ında, satır içi düzenlemede ve form sayfasında (`/admin/form/...`, `FormDevExpress`) aynı kuralla çalışır: alan değişince ebeveyni o alan olan çocuklar ve alanın `CascadeEmptyFields` diff --git a/api/src/Sozsoft.Platform.Application.Contracts/ListForms/GridOptionsDto/WorkflowDto.cs b/api/src/Sozsoft.Platform.Application.Contracts/ListForms/GridOptionsDto/WorkflowDto.cs index 2685c557..f24056dc 100644 --- a/api/src/Sozsoft.Platform.Application.Contracts/ListForms/GridOptionsDto/WorkflowDto.cs +++ b/api/src/Sozsoft.Platform.Application.Contracts/ListForms/GridOptionsDto/WorkflowDto.cs @@ -11,5 +11,11 @@ public class WorkflowDto public bool ApprovalIsFilterUserName { get; set; } public bool ApprovalIsResetWorkflow { get; set; } + /// + /// Açıksa yeni kayıt akışı kendiliğinden başlatmaz: kayıt taslak kalır, alt form satırları + /// onaydan önce girilebilir ve akış toolbar'daki başlat düğmesiyle başlar. + /// + public bool ApprovalIsManualStart { get; set; } + public List Criteria { get; set; } = []; } diff --git a/api/src/Sozsoft.Platform.Domain.Shared/PlatformConsts.cs b/api/src/Sozsoft.Platform.Domain.Shared/PlatformConsts.cs index 51c65b8a..929c7c27 100644 --- a/api/src/Sozsoft.Platform.Domain.Shared/PlatformConsts.cs +++ b/api/src/Sozsoft.Platform.Domain.Shared/PlatformConsts.cs @@ -1023,6 +1023,7 @@ public static class PlatformConsts public const string dxTextBox = "dxTextBox"; public const string dxImageViewer = "dxImageViewer"; public const string dxImageUpload = "dxImageUpload"; + public const string dxRating = "dxRating"; } public static class CustomEndpointConsts diff --git a/api/src/Sozsoft.Platform.Domain/Queries/Workflow.cs b/api/src/Sozsoft.Platform.Domain/Queries/Workflow.cs index b454d21b..d605f609 100644 --- a/api/src/Sozsoft.Platform.Domain/Queries/Workflow.cs +++ b/api/src/Sozsoft.Platform.Domain/Queries/Workflow.cs @@ -11,6 +11,7 @@ public class Workflow : ValueObject public string ApprovalDescriptionFieldName { get; set; } public bool ApprovalIsFilterUserName { get; set; } public bool ApprovalIsResetWorkflow { get; set; } + public bool ApprovalIsManualStart { get; set; } protected override IEnumerable GetAtomicValues() { @@ -20,6 +21,7 @@ public class Workflow : ValueObject yield return ApprovalDescriptionFieldName; yield return ApprovalIsFilterUserName; yield return ApprovalIsResetWorkflow; + yield return ApprovalIsManualStart; } } diff --git a/claude.md b/claude.md index f1e88148..caa9e18a 100644 --- a/claude.md +++ b/claude.md @@ -272,7 +272,7 @@ Bir çelişki varsa sıra: `ai.instructions.md` → `dotnet.instructions.md` → `phoneIntl`, `phoneCountry`) görüntü kuralı iki yerde yazılır: liste/kart istemcide, dinamik rapor sunucuda. Biri değişirse diğeri de değişir; yoksa liste ile rapor aynı numarayı farklı yazar. - **Liste popup'ı (Grid/Tree) ↔ form sayfası (`FormDevExpress`)** — editör yetenekleri ortak yardımcılardadır - (`list/shared/editingForm.ts`, `editingFormScripts.ts`, `cascade.ts`); TagBox/GridBox/ImageUpload/ImageViewer'ın + (`list/shared/editingForm.ts`, `editingFormScripts.ts`, `cascade.ts`); TagBox/GridBox/ImageUpload/ImageViewer/Rating'in tek uygulaması `form/editors/*`, liste hücresi yalnızca `list/editors/cellEditors.tsx` adaptörüdür. Bir tarafa yetenek eklenirken ortak yardımcıya eklenir; tek tarafa yazılan yetenek eşliği bozar. Tablo: `lowcode.instructions.md` §4.3.4. diff --git a/configs/seeds/data/App.Languages.LanguageText.json b/configs/seeds/data/App.Languages.LanguageText.json index 4f8cefed..8163392f 100644 --- a/configs/seeds/data/App.Languages.LanguageText.json +++ b/configs/seeds/data/App.Languages.LanguageText.json @@ -45770,6 +45770,20 @@ "Key": "App.ListFormEditWorkflow.ApprovalIsResetWorkflow", "Value": "İş Akışı Sıfırlama?" }, + { + "Id": "15424420-968a-5f95-a216-0457cdecd257", + "CultureName": "en", + "ResourceName": "Platform", + "Key": "App.ListFormEditWorkflow.ApprovalIsManualStart", + "Value": "Start Workflow Manually?" + }, + { + "Id": "ee2f23f5-49c8-5f81-a72c-10b4595443f4", + "CultureName": "tr", + "ResourceName": "Platform", + "Key": "App.ListFormEditWorkflow.ApprovalIsManualStart", + "Value": "Akış Elle Başlatılsın mı?" + }, { "Id": "b49643d5-247b-586b-a640-6c2ebf3fdcf4", "CultureName": "en", diff --git a/configs/seeds/docs/modules/App.Prc.md b/configs/seeds/docs/modules/App.Prc.md index 52f891b3..478412e0 100644 --- a/configs/seeds/docs/modules/App.Prc.md +++ b/configs/seeds/docs/modules/App.Prc.md @@ -78,7 +78,7 @@ Departmanların iç ve dış ihtiyaç duydukları malzemeleri satınalmaya iletm - Wizard List ekranları + menüsüz satır alt formu + Grid Workflow. Beş liste aynı tabloyu (`Prc_T_MaterialRequest`) filtreyle gösterir. - Belge no numaratörden: `MaterialRequest` (MT-YYYY-00001, yıllık sıfırlanır). Şirket alanı açılmadı (kiracı kapsamı). - Departman onaycısı: `Adm_T_Approver`'da Onay Yeri = Satınalma (`Purchase`) ve talebin departmanı. Satınalma onaycısı: Onaycılar'a eklenen yeni Onay Yeri **Satınalma Masası** (`PurchaseDesk`) satırları, departmandan bağımsız. Herhangi bir onaycının onayı yeterli. -- Taslak aşaması: kayıt Taslak açılır; akış platformun Onaya Gönder işlemiyle başlar. +- Taslak aşaması: kayıt Taslak açılır; akış platformun Onaya Gönder işlemiyle başlar (`WorkflowDto.ApprovalIsManualStart: true` — yoksa yeni kayıt akışı kendiliğinden başlatır ve satır girilemez). - Görseldeki "Kendi Depomda" ve "Tüm Depolar" stok kolonları üretilmedi: uygulamada stok miktarı/hareket tablosu yok; stok modülü gelince ayrı talep. - Karşılama Şekli: Satınalma / Depodan Transfer. - Onay akışının "onaylayan" alanı platformda kullanıcı adı (metin) yazdığı için akışa bağlanmadı (`ApprovalUserFieldName` boş); departman/satınalma onaylayanı kayıt sonrası prosedürde kaydı son güncelleyen kullanıcıdan yazılır. `ApproverId` kolonu kullanılmaz. @@ -295,7 +295,7 @@ Yönetim › Tanımlamalar › Onaycılar (onay yerleri Satınalma ve Satınalma | Alan | Başlık | Editör | Zorunlu | Formda | Kaynak | | --- | --- | --- | --- | --- | --- | | `RequestNo` | Talep No | dxTextBox | | ✓ | | -| `Priority` | Öncelik (0-3) | dxNumberBox | ✓ | ✓ | | +| `Priority` | Öncelik (0-3) | dxRating | ✓ | ✓ | | | `RequesterUserId` | Talep Eden | dxSelectBox | ✓ | ✓ | sorgu: AbpUsers · script | | `DepartmentId` | Departman | dxSelectBox | ✓ | ✓ | sorgu: Hr_T_Department | | `WarehouseId` | Depo | dxSelectBox | ✓ | ✓ | sorgu: Inv_T_Warehouse · script | @@ -340,7 +340,7 @@ Yönetim › Tanımlamalar › Onaycılar (onay yerleri Satınalma ve Satınalma | Alan | Başlık | Editör | Zorunlu | Formda | Kaynak | | --- | --- | --- | --- | --- | --- | | `RequestNo` | Talep No | dxTextBox | | ✓ | | -| `Priority` | Öncelik (0-3) | dxNumberBox | ✓ | ✓ | | +| `Priority` | Öncelik (0-3) | dxRating | ✓ | ✓ | | | `RequesterUserId` | Talep Eden | dxSelectBox | ✓ | ✓ | sorgu: AbpUsers | | `DepartmentId` | Departman | dxSelectBox | ✓ | ✓ | sorgu: Hr_T_Department | | `WarehouseId` | Depo | dxSelectBox | ✓ | ✓ | sorgu: Inv_T_Warehouse | @@ -378,7 +378,7 @@ Yönetim › Tanımlamalar › Onaycılar (onay yerleri Satınalma ve Satınalma | Alan | Başlık | Editör | Zorunlu | Formda | Kaynak | | --- | --- | --- | --- | --- | --- | | `RequestNo` | Talep No | dxTextBox | | ✓ | | -| `Priority` | Öncelik (0-3) | dxNumberBox | ✓ | ✓ | | +| `Priority` | Öncelik (0-3) | dxRating | ✓ | ✓ | | | `RequesterUserId` | Talep Eden | dxSelectBox | ✓ | ✓ | sorgu: AbpUsers | | `DepartmentId` | Departman | dxSelectBox | ✓ | ✓ | sorgu: Hr_T_Department | | `WarehouseId` | Depo | dxSelectBox | ✓ | ✓ | sorgu: Inv_T_Warehouse | @@ -418,7 +418,7 @@ Yönetim › Tanımlamalar › Onaycılar (onay yerleri Satınalma ve Satınalma | Alan | Başlık | Editör | Zorunlu | Formda | Kaynak | | --- | --- | --- | --- | --- | --- | | `RequestNo` | Talep No | dxTextBox | | ✓ | | -| `Priority` | Öncelik (0-3) | dxNumberBox | ✓ | ✓ | | +| `Priority` | Öncelik (0-3) | dxRating | ✓ | ✓ | | | `RequesterUserId` | Talep Eden | dxSelectBox | ✓ | ✓ | sorgu: AbpUsers | | `DepartmentId` | Departman | dxSelectBox | ✓ | ✓ | sorgu: Hr_T_Department | | `WarehouseId` | Depo | dxSelectBox | ✓ | ✓ | sorgu: Inv_T_Warehouse | @@ -456,7 +456,7 @@ Yönetim › Tanımlamalar › Onaycılar (onay yerleri Satınalma ve Satınalma | Alan | Başlık | Editör | Zorunlu | Formda | Kaynak | | --- | --- | --- | --- | --- | --- | | `RequestNo` | Talep No | dxTextBox | | ✓ | | -| `Priority` | Öncelik (0-3) | dxNumberBox | ✓ | ✓ | | +| `Priority` | Öncelik (0-3) | dxRating | ✓ | ✓ | | | `RequesterUserId` | Talep Eden | dxSelectBox | ✓ | ✓ | sorgu: AbpUsers · script | | `DepartmentId` | Departman | dxSelectBox | ✓ | ✓ | sorgu: Hr_T_Department | | `WarehouseId` | Depo | dxSelectBox | ✓ | ✓ | sorgu: Inv_T_Warehouse · script | diff --git a/configs/seeds/wizard/Prc_MaterialRequest.json b/configs/seeds/wizard/Prc_MaterialRequest.json index 1640eb3f..da015923 100644 --- a/configs/seeds/wizard/Prc_MaterialRequest.json +++ b/configs/seeds/wizard/Prc_MaterialRequest.json @@ -656,6 +656,7 @@ "ApprovalDescriptionFieldName": "ApprovalNote", "ApprovalIsFilterUserName": false, "ApprovalIsResetWorkflow": true, + "ApprovalIsManualStart": false, "Criteria": [ { "ListFormCode": "App.Prc.MaterialRequest", @@ -1385,7 +1386,7 @@ "Format": null, "EditOrderNo": 2, "EditGroupOrderNo": 1, - "EditorType2": "dxNumberBox", + "EditorType2": "dxRating", "ColSpan": 1, "EditorOptions": "{\"min\":0,\"max\":3,\"showSpinButtons\":true}", "GridBoxOptions": null, diff --git a/configs/seeds/wizard/Prc_MaterialRequestDeptApproval.json b/configs/seeds/wizard/Prc_MaterialRequestDeptApproval.json index 428812b1..3beafa91 100644 --- a/configs/seeds/wizard/Prc_MaterialRequestDeptApproval.json +++ b/configs/seeds/wizard/Prc_MaterialRequestDeptApproval.json @@ -509,8 +509,8 @@ "Order": 1, "ItemType": "group", "Caption": "", - "ColCount": 2, - "ColSpan": 2 + "ColCount": 4, + "ColSpan": 4 } ], "PermissionDto": { @@ -575,6 +575,7 @@ "ApprovalDescriptionFieldName": "ApprovalNote", "ApprovalIsFilterUserName": true, "ApprovalIsResetWorkflow": true, + "ApprovalIsManualStart": false, "Criteria": [ { "ListFormCode": "App.Prc.MaterialRequestDeptApproval", @@ -1036,7 +1037,7 @@ "GroupInterval": "", "WordWrapEnabled": false }, - "Alignment": null, + "Alignment": "left", "Format": null, "EditOrderNo": null, "EditGroupOrderNo": null, @@ -1162,7 +1163,7 @@ "GroupInterval": "", "WordWrapEnabled": false }, - "Alignment": null, + "Alignment": "left", "Format": null, "EditOrderNo": 1, "EditGroupOrderNo": 1, @@ -1300,11 +1301,11 @@ "GroupInterval": "", "WordWrapEnabled": false }, - "Alignment": null, + "Alignment": "left", "Format": null, "EditOrderNo": 2, "EditGroupOrderNo": 1, - "EditorType2": "dxNumberBox", + "EditorType2": "dxRating", "ColSpan": 1, "EditorOptions": "{\"readOnly\":true}", "GridBoxOptions": null, @@ -1438,7 +1439,7 @@ "GroupInterval": "", "WordWrapEnabled": false }, - "Alignment": null, + "Alignment": "left", "Format": null, "EditOrderNo": 3, "EditGroupOrderNo": 1, @@ -1576,7 +1577,7 @@ "GroupInterval": "", "WordWrapEnabled": false }, - "Alignment": null, + "Alignment": "left", "Format": null, "EditOrderNo": 4, "EditGroupOrderNo": 1, @@ -1714,7 +1715,7 @@ "GroupInterval": "", "WordWrapEnabled": false }, - "Alignment": null, + "Alignment": "left", "Format": null, "EditOrderNo": 5, "EditGroupOrderNo": 1, @@ -1852,7 +1853,7 @@ "GroupInterval": "", "WordWrapEnabled": false }, - "Alignment": null, + "Alignment": "left", "Format": null, "EditOrderNo": 6, "EditGroupOrderNo": 1, @@ -1990,7 +1991,7 @@ "GroupInterval": "", "WordWrapEnabled": false }, - "Alignment": null, + "Alignment": "left", "Format": null, "EditOrderNo": 7, "EditGroupOrderNo": 1, @@ -2128,7 +2129,7 @@ "GroupInterval": "", "WordWrapEnabled": false }, - "Alignment": null, + "Alignment": "left", "Format": null, "EditOrderNo": 8, "EditGroupOrderNo": 1, @@ -2254,7 +2255,7 @@ "GroupInterval": "", "WordWrapEnabled": false }, - "Alignment": null, + "Alignment": "left", "Format": null, "EditOrderNo": 9, "EditGroupOrderNo": 1, @@ -2380,12 +2381,12 @@ "GroupInterval": "", "WordWrapEnabled": false }, - "Alignment": null, + "Alignment": "left", "Format": null, "EditOrderNo": 10, "EditGroupOrderNo": 1, "EditorType2": "dxSelectBox", - "ColSpan": 1, + "ColSpan": 3, "EditorOptions": "{\"showClearButton\":true}", "GridBoxOptions": null, "TagBoxOptions": null, @@ -2506,12 +2507,12 @@ "GroupInterval": "", "WordWrapEnabled": false }, - "Alignment": null, + "Alignment": "left", "Format": null, "EditOrderNo": 11, "EditGroupOrderNo": 1, "EditorType2": "dxTextArea", - "ColSpan": 2, + "ColSpan": 4, "EditorOptions": "{\"readOnly\":true}", "GridBoxOptions": null, "TagBoxOptions": null, @@ -2632,7 +2633,7 @@ "GroupInterval": "", "WordWrapEnabled": false }, - "Alignment": null, + "Alignment": "left", "Format": null, "EditOrderNo": null, "EditGroupOrderNo": null, @@ -2758,7 +2759,7 @@ "GroupInterval": "", "WordWrapEnabled": false }, - "Alignment": null, + "Alignment": "left", "Format": null, "EditOrderNo": null, "EditGroupOrderNo": null, @@ -2884,7 +2885,7 @@ "GroupInterval": "", "WordWrapEnabled": false }, - "Alignment": null, + "Alignment": "left", "Format": null, "EditOrderNo": null, "EditGroupOrderNo": null, @@ -3010,7 +3011,7 @@ "GroupInterval": "", "WordWrapEnabled": false }, - "Alignment": null, + "Alignment": "left", "Format": null, "EditOrderNo": null, "EditGroupOrderNo": null, diff --git a/configs/seeds/wizard/Prc_MaterialRequestPlanning.json b/configs/seeds/wizard/Prc_MaterialRequestPlanning.json index c342b5fd..b67e8f3c 100644 --- a/configs/seeds/wizard/Prc_MaterialRequestPlanning.json +++ b/configs/seeds/wizard/Prc_MaterialRequestPlanning.json @@ -586,6 +586,7 @@ "ApprovalDescriptionFieldName": null, "ApprovalIsFilterUserName": false, "ApprovalIsResetWorkflow": false, + "ApprovalIsManualStart": false, "Criteria": [] }, "UserId": null, @@ -1224,7 +1225,7 @@ "Format": null, "EditOrderNo": 2, "EditGroupOrderNo": 1, - "EditorType2": "dxNumberBox", + "EditorType2": "dxRating", "ColSpan": 1, "EditorOptions": "{\"readOnly\":true}", "GridBoxOptions": null, diff --git a/configs/seeds/wizard/Prc_MaterialRequestPurchaseApproval.json b/configs/seeds/wizard/Prc_MaterialRequestPurchaseApproval.json index 36afa8dc..f235b439 100644 --- a/configs/seeds/wizard/Prc_MaterialRequestPurchaseApproval.json +++ b/configs/seeds/wizard/Prc_MaterialRequestPurchaseApproval.json @@ -604,6 +604,7 @@ "ApprovalDescriptionFieldName": "ApprovalNote", "ApprovalIsFilterUserName": true, "ApprovalIsResetWorkflow": true, + "ApprovalIsManualStart": false, "Criteria": [ { "ListFormCode": "App.Prc.MaterialRequestPurchaseApproval", @@ -1065,7 +1066,7 @@ "GroupInterval": "", "WordWrapEnabled": false }, - "Alignment": null, + "Alignment": "left", "Format": null, "EditOrderNo": null, "EditGroupOrderNo": null, @@ -1191,7 +1192,7 @@ "GroupInterval": "", "WordWrapEnabled": false }, - "Alignment": null, + "Alignment": "left", "Format": null, "EditOrderNo": 1, "EditGroupOrderNo": 1, @@ -1329,11 +1330,11 @@ "GroupInterval": "", "WordWrapEnabled": false }, - "Alignment": null, + "Alignment": "left", "Format": null, "EditOrderNo": 2, "EditGroupOrderNo": 1, - "EditorType2": "dxNumberBox", + "EditorType2": "dxRating", "ColSpan": 1, "EditorOptions": "{\"readOnly\":true}", "GridBoxOptions": null, @@ -1467,7 +1468,7 @@ "GroupInterval": "", "WordWrapEnabled": false }, - "Alignment": null, + "Alignment": "left", "Format": null, "EditOrderNo": 3, "EditGroupOrderNo": 1, @@ -1605,7 +1606,7 @@ "GroupInterval": "", "WordWrapEnabled": false }, - "Alignment": null, + "Alignment": "left", "Format": null, "EditOrderNo": 4, "EditGroupOrderNo": 1, @@ -1743,7 +1744,7 @@ "GroupInterval": "", "WordWrapEnabled": false }, - "Alignment": null, + "Alignment": "left", "Format": null, "EditOrderNo": 5, "EditGroupOrderNo": 1, @@ -1881,7 +1882,7 @@ "GroupInterval": "", "WordWrapEnabled": false }, - "Alignment": null, + "Alignment": "left", "Format": null, "EditOrderNo": 6, "EditGroupOrderNo": 1, @@ -2019,7 +2020,7 @@ "GroupInterval": "", "WordWrapEnabled": false }, - "Alignment": null, + "Alignment": "left", "Format": null, "EditOrderNo": 7, "EditGroupOrderNo": 1, @@ -2157,7 +2158,7 @@ "GroupInterval": "", "WordWrapEnabled": false }, - "Alignment": null, + "Alignment": "left", "Format": null, "EditOrderNo": 8, "EditGroupOrderNo": 1, @@ -2283,7 +2284,7 @@ "GroupInterval": "", "WordWrapEnabled": false }, - "Alignment": null, + "Alignment": "left", "Format": null, "EditOrderNo": 9, "EditGroupOrderNo": 1, @@ -2409,7 +2410,7 @@ "GroupInterval": "", "WordWrapEnabled": false }, - "Alignment": null, + "Alignment": "left", "Format": null, "EditOrderNo": 10, "EditGroupOrderNo": 1, @@ -2535,7 +2536,7 @@ "GroupInterval": "", "WordWrapEnabled": false }, - "Alignment": null, + "Alignment": "left", "Format": null, "EditOrderNo": 11, "EditGroupOrderNo": 1, @@ -2661,7 +2662,7 @@ "GroupInterval": "", "WordWrapEnabled": false }, - "Alignment": null, + "Alignment": "left", "Format": null, "EditOrderNo": null, "EditGroupOrderNo": null, @@ -2787,7 +2788,7 @@ "GroupInterval": "", "WordWrapEnabled": false }, - "Alignment": null, + "Alignment": "left", "Format": null, "EditOrderNo": null, "EditGroupOrderNo": null, @@ -2913,7 +2914,7 @@ "GroupInterval": "", "WordWrapEnabled": false }, - "Alignment": null, + "Alignment": "left", "Format": null, "EditOrderNo": null, "EditGroupOrderNo": null, @@ -3039,7 +3040,7 @@ "GroupInterval": "", "WordWrapEnabled": false }, - "Alignment": null, + "Alignment": "left", "Format": null, "EditOrderNo": null, "EditGroupOrderNo": null, @@ -3165,7 +3166,7 @@ "GroupInterval": "", "WordWrapEnabled": false }, - "Alignment": null, + "Alignment": "left", "Format": null, "EditOrderNo": 1, "EditGroupOrderNo": 2, @@ -3291,7 +3292,7 @@ "GroupInterval": "", "WordWrapEnabled": false }, - "Alignment": null, + "Alignment": "left", "Format": null, "EditOrderNo": 2, "EditGroupOrderNo": 2, @@ -3417,7 +3418,7 @@ "GroupInterval": "", "WordWrapEnabled": false }, - "Alignment": null, + "Alignment": "left", "Format": null, "EditOrderNo": 3, "EditGroupOrderNo": 2, diff --git a/configs/seeds/wizard/Prc_MyMaterialRequest.json b/configs/seeds/wizard/Prc_MyMaterialRequest.json index c7065dfc..5d6c5742 100644 --- a/configs/seeds/wizard/Prc_MyMaterialRequest.json +++ b/configs/seeds/wizard/Prc_MyMaterialRequest.json @@ -670,12 +670,13 @@ "DefaultLayout": "grid" }, "WorkflowDto": { - "ApprovalUserFieldName": null, + "ApprovalUserFieldName": "ApproverId", "ApprovalDateFieldName": "ApprovalDate", "ApprovalStatusFieldName": "ApprovalStatus", "ApprovalDescriptionFieldName": "ApprovalNote", "ApprovalIsFilterUserName": false, "ApprovalIsResetWorkflow": true, + "ApprovalIsManualStart": false, "Criteria": [ { "ListFormCode": "App.Prc.MyMaterialRequest", @@ -1405,7 +1406,7 @@ "Format": null, "EditOrderNo": 2, "EditGroupOrderNo": 1, - "EditorType2": "dxNumberBox", + "EditorType2": "dxRating", "ColSpan": 1, "EditorOptions": "{\"min\":0,\"max\":3,\"showSpinButtons\":true}", "GridBoxOptions": null, diff --git a/ui/src/components/ui/Rate/Rate.tsx b/ui/src/components/ui/Rate/Rate.tsx index 1458000e..4d930124 100644 --- a/ui/src/components/ui/Rate/Rate.tsx +++ b/ui/src/components/ui/Rate/Rate.tsx @@ -1,15 +1,9 @@ -import React, { - forwardRef, - useState, - useCallback, - useRef, - type KeyboardEvent, - type ReactNode, -} from 'react' +import React, { forwardRef, useState, useCallback, type KeyboardEvent, type ReactNode } from 'react' import classNames from 'classnames' import { useConfig } from '../ConfigProvider' import type { CommonProps } from '../@types/common' import { useLocalization } from '@/utils/hooks/useLocalization' +import { RATE_STAR_POINTS } from './starShape' export interface RateProps extends CommonProps { /** Toplam yıldız sayısı. Varsayılan: 5 */ @@ -59,7 +53,7 @@ const StarIcon = ({ filled, half, size }: { filled: boolean; half: boolean; size )} ((props, ref) => { const isControlled = valueProp !== undefined const [internalValue, setInternalValue] = useState(defaultValue) const [hoverValue, setHoverValue] = useState(null) - const lastClickedRef = useRef(null) const value = isControlled ? valueProp! : internalValue const displayValue = hoverValue !== null ? hoverValue : value @@ -139,18 +132,14 @@ const Rate = forwardRef((props, ref) => { const offsetX = e.clientX - rect.left const clickedVal = getStarValue(index, offsetX, rect.width) - let newVal = clickedVal - if (allowClear && clickedVal === lastClickedRef.current) { - newVal = 0 - lastClickedRef.current = null - } else { - lastClickedRef.current = clickedVal - } + // Seçili yıldıza yeniden tıklamak değeri sıfırlar; karşılaştırma son tıklamayla değil + // güncel değerle yapılır, yoksa kontrollü kullanımda dışarıdan gelen değer temizlenemez. + const newVal = allowClear && clickedVal === value ? 0 : clickedVal if (!isControlled) setInternalValue(newVal) onChange?.(newVal) }, - [disabled, readOnly, allowClear, allowHalf, isControlled, onChange], + [disabled, readOnly, allowClear, allowHalf, value, isControlled, onChange], ) const handleKeyDown = useCallback( diff --git a/ui/src/components/ui/Rate/starShape.ts b/ui/src/components/ui/Rate/starShape.ts new file mode 100644 index 00000000..609b91ba --- /dev/null +++ b/ui/src/components/ui/Rate/starShape.ts @@ -0,0 +1,3 @@ +/** Yıldız çokgeni; `Rate` ve liste hücresi (DOM şablonu) aynı şekli çizer. */ +export const RATE_STAR_POINTS = + '12,2 15.09,8.26 22,9.27 17,14.14 18.18,21.02 12,17.77 5.82,21.02 7,14.14 2,9.27 8.91,8.26' diff --git a/ui/src/proxy/form/models.ts b/ui/src/proxy/form/models.ts index 8585b4dd..499dc896 100644 --- a/ui/src/proxy/form/models.ts +++ b/ui/src/proxy/form/models.ts @@ -871,6 +871,7 @@ export enum PlatformEditorTypes { dxGridBox = 'dxGridBox', dxImageViewer = 'dxImageViewer', dxImageUpload = 'dxImageUpload', + dxRating = 'dxRating', } export enum GanttScaleTypeEnum { @@ -948,6 +949,7 @@ export interface WorkflowDto { approvalDescriptionFieldName: string approvalIsFilterUserName: boolean approvalIsResetWorkflow: boolean + approvalIsManualStart: boolean criteria: ListFormWorkflowCriteriaDto[] } diff --git a/ui/src/views/admin/listForm/edit/FormTabWorkflow.tsx b/ui/src/views/admin/listForm/edit/FormTabWorkflow.tsx index 7b6100e5..e1962e98 100644 --- a/ui/src/views/admin/listForm/edit/FormTabWorkflow.tsx +++ b/ui/src/views/admin/listForm/edit/FormTabWorkflow.tsx @@ -319,14 +319,25 @@ export function FormTabWorkflow( approvalDescriptionFieldName: string(), approvalIsFilterUserName: bool(), approvalIsResetWorkflow: bool(), + approvalIsManualStart: bool(), }), }) - const initialValues = useStoreState((s) => s.admin.lists.values) - if (!initialValues) { + const listValues = useStoreState((s) => s.admin.lists.values) + if (!listValues) { return null } + // Seçenek eklenmeden önce kaydedilmiş WorkflowJson'da alan yoktur; değeri tanımsız checkbox'ı + // Formik dizi olarak yazar (["on"]) ve boolean doğrulaması düşer. + const initialValues = { + ...listValues, + workflowDto: { + ...listValues.workflowDto, + approvalIsManualStart: Boolean(listValues.workflowDto?.approvalIsManualStart), + }, + } + return (
-
+
+ + + +