Document SignalR architecture, grid, and ext deps
Added comprehensive docs for SignalR tag-based dispatch (docs/SIGNALR_ARCHITECTURE.md), including message flow, tag system, dynamic method registry, and tech debt (JSON-in-Binary). Updated all related READMEs, glossaries, and conventions to reference this architecture and clarify grid infrastructure (MgGridBase, FruitBankGridBase) and external dependency locations (AyCode.Core, AyCode.Blazor, Mango.Nop Libraries, FruitBank Plugin). Synchronized solution items and copilot-instructions. Improves discoverability, enforces conventions, and clarifies tech debt for all developers.
This commit is contained in:
parent
e2c49940c6
commit
8c90a6ba51
|
|
@ -2,6 +2,9 @@
|
||||||
|
|
||||||
> This is the **single source of truth** for domain rules. Do not duplicate these elsewhere.
|
> This is the **single source of truth** for domain rules. Do not duplicate these elsewhere.
|
||||||
> For detailed docs see: `README.md` → `docs/`
|
> For detailed docs see: `README.md` → `docs/`
|
||||||
|
> For core framework rules see: `../../../Aycode/Source/AyCode.Core/.github/copilot-instructions.md`
|
||||||
|
> For UI framework rules see: `../../../Aycode/Source/AyCode.Blazor/.github/copilot-instructions.md`
|
||||||
|
> For nopCommerce library rules see: `../NopCommerce.Common/4.70/Libraries/.github/copilot-instructions.md`
|
||||||
|
|
||||||
## Business Domain
|
## Business Domain
|
||||||
1. **FruitBank** = fruit & vegetable wholesaler. This is a **nopCommerce plugin** — Customer, Order, Product, GenericAttribute are nopCommerce entities.
|
1. **FruitBank** = fruit & vegetable wholesaler. This is a **nopCommerce plugin** — Customer, Order, Product, GenericAttribute are nopCommerce entities.
|
||||||
|
|
@ -27,3 +30,8 @@
|
||||||
12. All AyCode references are via **DLL** (not ProjectReference) — this is intentional. nopCommerce 4.80.9 requirement.
|
12. All AyCode references are via **DLL** (not ProjectReference) — this is intentional. nopCommerce 4.80.9 requirement.
|
||||||
13. **No redundant code** — before writing new logic, search for existing methods. Reuse or extract shared logic into smaller methods rather than duplicating.
|
13. **No redundant code** — before writing new logic, search for existing methods. Reuse or extract shared logic into smaller methods rather than duplicating.
|
||||||
14. **Keep all .md files in sync** — when you modify code, update any affected .md file (README.md, docs/, GLOSSARY, ARCHITECTURE, CONVENTIONS, SCHEMA, etc.). If you notice any .md content does not match the current code, fix it automatically.
|
14. **Keep all .md files in sync** — when you modify code, update any affected .md file (README.md, docs/, GLOSSARY, ARCHITECTURE, CONVENTIONS, SCHEMA, etc.). If you notice any .md content does not match the current code, fix it automatically.
|
||||||
|
15. **MgGridBase** (AyCode.Blazor) is the canonical grid base for all data screens. New grids inherit `FruitBankGridBase<TEntity>`, set CRUD tags in the constructor, and use `MgGridWithInfoPanel` for layout. See `AyCode.Blazor/docs/MGGRID.md` for the full technical reference. Do NOT create parallel grid base classes.
|
||||||
|
16. **AyCode.Core** solution (`../../../Aycode/Source/AyCode.Core/`) contains all core framework code: SignalR base classes, serialization, binary protocol, data sources, logging. When a type is referenced but not defined in this solution, look it up in AyCode.Core source and docs.
|
||||||
|
17. **AyCode.Blazor** solution (`../../../Aycode/Source/AyCode.Blazor/`) contains all UI framework code: MgGridBase, MgGridWithInfoPanel, toolbar, layout persistence, Blazor component infrastructure. When a UI base class or component is not found here, look it up in AyCode.Blazor source and docs.
|
||||||
|
18. **Mango.Nop Libraries** (`../NopCommerce.Common/4.70/Libraries/`) — independent shared library with its own `.github/copilot-instructions.md` and `docs/`. Contains DTOs, entities, data access, and service base classes. When a DTO or entity base class is not found in this solution, look it up in the Libraries source and docs.
|
||||||
|
19. **FruitBank nopCommerce Plugin** (`../NopCommerce.Common/4.70/Plugins/Nop.Plugin.Misc.AIPlugin/`) is the server-side plugin running inside nopCommerce 4.80.9. Contains SignalR hubs/endpoints, measurement services, data access (DbTable classes), admin controllers, and AI services. When a server-side endpoint or service is referenced, look it up here.
|
||||||
|
|
|
||||||
23
CLAUDE.md
23
CLAUDE.md
|
|
@ -6,6 +6,27 @@ Before writing any code, read these files:
|
||||||
3. `docs/SCHEMA.md` — Full domain model in Toon format
|
3. `docs/SCHEMA.md` — Full domain model in Toon format
|
||||||
4. The relevant project's `README.md` for folder-specific context
|
4. The relevant project's `README.md` for folder-specific context
|
||||||
|
|
||||||
This solution depends on **AyCode.Core** and **AyCode.Blazor** frameworks.
|
## External Repos
|
||||||
|
|
||||||
|
This solution depends on external code in sibling directories. Their **full source code** is available — browse them freely for type definitions, base classes, patterns, and docs:
|
||||||
|
|
||||||
|
| Repo | Path (relative to this repo root) | Contains |
|
||||||
|
|---|---|---|
|
||||||
|
| **AyCode.Core** | `../../../Aycode/Source/AyCode.Core/` | SignalR base classes, serialization, binary protocol, data sources, logging |
|
||||||
|
| **AyCode.Blazor** | `../../../Aycode/Source/AyCode.Blazor/` | MgGridBase, MgGridWithInfoPanel, toolbar, layout persistence, Blazor components |
|
||||||
|
| **Mango.Nop Libraries** | `../NopCommerce.Common/4.70/Libraries/` | Independent shared library with own `.github/copilot-instructions.md` and `docs/`. DTOs, entities, data access, service base classes |
|
||||||
|
| **FruitBank Plugin** | `../NopCommerce.Common/4.70/Plugins/Nop.Plugin.Misc.AIPlugin/` | nopCommerce 4.80.9 server-side plugin: SignalR hubs, measurement services, DbTable classes, admin controllers, AI services |
|
||||||
|
|
||||||
|
Key docs in those repos:
|
||||||
|
- `../../../Aycode/Source/AyCode.Core/.github/copilot-instructions.md` — core framework rules
|
||||||
|
- `../../../Aycode/Source/AyCode.Core/docs/ARCHITECTURE.md` — core architecture
|
||||||
|
- `../../../Aycode/Source/AyCode.Blazor/.github/copilot-instructions.md` — UI framework rules
|
||||||
|
- `../../../Aycode/Source/AyCode.Blazor/docs/MGGRID.md` — MgGrid technical reference
|
||||||
|
- `../../../Aycode/Source/AyCode.Blazor/docs/ARCHITECTURE.md` — UI architecture
|
||||||
|
- `../NopCommerce.Common/4.70/Libraries/.github/copilot-instructions.md` — Mango.Nop library rules
|
||||||
|
- `../NopCommerce.Common/4.70/Libraries/docs/ARCHITECTURE.md` — library architecture + NopDependencies pattern
|
||||||
|
- `../NopCommerce.Common/4.70/Plugins/Nop.Plugin.Misc.AIPlugin/README.md` — FruitBank plugin overview
|
||||||
|
|
||||||
|
When a type is referenced but not defined in this solution, look it up in AyCode.Core, AyCode.Blazor, or the Mango.Nop Libraries. When a server-side endpoint or service is referenced, look it up in the FruitBank Plugin.
|
||||||
|
|
||||||
When modifying code, update the corresponding README.md if it becomes out of sync with the code.
|
When modifying code, update the corresponding README.md if it becomes out of sync with the code.
|
||||||
|
|
|
||||||
11
README.md
11
README.md
|
|
@ -33,3 +33,14 @@ Detailed docs: [`docs/`](docs/) — GLOSSARY.md, ARCHITECTURE.md, CONVENTIONS.md
|
||||||
| Project | TFM | Purpose | README |
|
| Project | TFM | Purpose | README |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| [`FruitBankHybrid.Shared.Tests`](FruitBankHybrid.Shared.Tests/README.md) | net10.0 | Integration + serialization tests (SignalR, JSON, Toon, bunit) | [README](FruitBankHybrid.Shared.Tests/README.md) |
|
| [`FruitBankHybrid.Shared.Tests`](FruitBankHybrid.Shared.Tests/README.md) | net10.0 | Integration + serialization tests (SignalR, JSON, Toon, bunit) | [README](FruitBankHybrid.Shared.Tests/README.md) |
|
||||||
|
|
||||||
|
### External Dependencies
|
||||||
|
|
||||||
|
All projects reference these via **DLL** (not ProjectReference). Full source is available in sibling directories:
|
||||||
|
|
||||||
|
| Repo | Path | Key Docs |
|
||||||
|
|---|---|---|
|
||||||
|
| **AyCode.Core** (net9.0) | `../../../Aycode/Source/AyCode.Core/` | [copilot-instructions](../../../Aycode/Source/AyCode.Core/.github/copilot-instructions.md), [ARCHITECTURE](../../../Aycode/Source/AyCode.Core/docs/ARCHITECTURE.md) |
|
||||||
|
| **AyCode.Blazor** (net10.0) | `../../../Aycode/Source/AyCode.Blazor/` | [copilot-instructions](../../../Aycode/Source/AyCode.Blazor/.github/copilot-instructions.md), [MGGRID](../../../Aycode/Source/AyCode.Blazor/docs/MGGRID.md) |
|
||||||
|
| **Mango.Nop Libraries** (net9.0) | `../NopCommerce.Common/4.70/Libraries/` | [copilot-instructions](../NopCommerce.Common/4.70/Libraries/.github/copilot-instructions.md), [ARCHITECTURE](../NopCommerce.Common/4.70/Libraries/docs/ARCHITECTURE.md) |
|
||||||
|
| **FruitBank Plugin** (net9.0) | `../NopCommerce.Common/4.70/Plugins/Nop.Plugin.Misc.AIPlugin/` | [README](../NopCommerce.Common/4.70/Plugins/Nop.Plugin.Misc.AIPlugin/README.md) |
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,12 @@ FruitBankHybrid FruitBankHybrid.Web FruitBankHybrid.Web.Client
|
||||||
|
|
||||||
All projects also reference **AyCode.Core** (net9.0) and **AyCode.Blazor** (net10.0) via DLL references (not ProjectReference).
|
All projects also reference **AyCode.Core** (net9.0) and **AyCode.Blazor** (net10.0) via DLL references (not ProjectReference).
|
||||||
|
|
||||||
|
> **Context:** When a type or base class is not found in this solution, browse the external repos:
|
||||||
|
> - **AyCode.Core**: `../../../Aycode/Source/AyCode.Core/` — SignalR, serialization, binary protocol, data sources
|
||||||
|
> - **AyCode.Blazor**: `../../../Aycode/Source/AyCode.Blazor/` — MgGridBase, UI components, layout persistence
|
||||||
|
> - **Mango.Nop Libraries**: `../NopCommerce.Common/4.70/Libraries/` — independent library with own [copilot-instructions](../NopCommerce.Common/4.70/Libraries/.github/copilot-instructions.md) and [docs/](../NopCommerce.Common/4.70/Libraries/docs/)
|
||||||
|
> - **FruitBank Plugin**: `../NopCommerce.Common/4.70/Plugins/Nop.Plugin.Misc.AIPlugin/` — server-side SignalR hubs, measurement services, DbTable classes
|
||||||
|
|
||||||
## Target Frameworks
|
## Target Frameworks
|
||||||
|
|
||||||
nopCommerce 4.80.9 requires .NET 9
|
nopCommerce 4.80.9 requires .NET 9
|
||||||
|
|
@ -59,11 +65,84 @@ User → DevExpress Grid → AcSignalRDataSource → SignalR (AcBinary) → DevA
|
||||||
nopCommerce Database
|
nopCommerce Database
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## MgGrid — Grid System
|
||||||
|
|
||||||
|
All data screens use **MgGridBase** from AyCode.Blazor (see [AyCode.Blazor/docs/MGGRID.md](../../../Aycode/Source/AyCode.Blazor/docs/MGGRID.md) for full technical docs).
|
||||||
|
|
||||||
|
### FruitBank Grid Hierarchy
|
||||||
|
|
||||||
|
```
|
||||||
|
MgGridBase<TSignalRDataSource, TDataItem, TId, TLoggerClient> (AyCode.Blazor)
|
||||||
|
└── FruitBankGridBase<TDataItem> (FruitBankHybrid.Shared)
|
||||||
|
├── GridShippingBase → Shipping
|
||||||
|
├── GridShippingDocumentBase → ShippingDocument (detail of Shipping)
|
||||||
|
├── GridPartnerBase → Partner
|
||||||
|
├── GridGenericAttributeBase → GenericAttributeDto
|
||||||
|
└── GridStockTakingItemBase → StockTakingItem
|
||||||
|
```
|
||||||
|
|
||||||
|
### FruitBankGridBase<TDataItem>
|
||||||
|
|
||||||
|
Project-level adapter that fixes 3 of 4 generic parameters:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public class FruitBankGridBase<TDataItem>
|
||||||
|
: MgGridBase<SignalRDataSourceObservable<TDataItem>, TDataItem, int, LoggerClient>
|
||||||
|
```
|
||||||
|
|
||||||
|
Adds FruitBank-specific defaults:
|
||||||
|
- `GetLayoutUserId()` → `LoggedInModel.CustomerDto?.Id ?? 0` (per-user layout)
|
||||||
|
- Master grid: filter row, group panel, search box, `PageSize=20`, `EditMode=EditRow`
|
||||||
|
- Detail grid: no filter/group/search, `PageSize=10`
|
||||||
|
- Alternating row style (`.alt-item`), header background (`#E6E6E6`)
|
||||||
|
- Detail rows hidden for non-admin users (`hideDetailButton` CSS)
|
||||||
|
|
||||||
|
### SignalR Tag Mapping
|
||||||
|
|
||||||
|
Each concrete grid sets CRUD tags in its constructor:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public GridShippingBase()
|
||||||
|
{
|
||||||
|
GetAllMessageTag = SignalRTags.GetShippings; // e.g. 300
|
||||||
|
AddMessageTag = SignalRTags.AddShipping; // e.g. 302
|
||||||
|
UpdateMessageTag = SignalRTags.UpdateShipping; // e.g. 303
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Tags are defined in `FruitBank.Common/SignalRs/SignalRTags.cs` with numeric ranges per domain area.
|
||||||
|
|
||||||
|
### Grid Usage Pattern (Razor)
|
||||||
|
|
||||||
|
```razor
|
||||||
|
<MgGridWithInfoPanel ShowInfoPanel="@IsMasterGrid">
|
||||||
|
<GridContent>
|
||||||
|
<GridShippingBase @ref="Grid"
|
||||||
|
DataSource="Shippings"
|
||||||
|
AutoSaveLayoutName="GridShipping"
|
||||||
|
SignalRClient="FruitBankSignalRClient"
|
||||||
|
Logger="_logger"
|
||||||
|
OnGridFocusedRowChanged="Grid_FocusedRowChanged">
|
||||||
|
<Columns>
|
||||||
|
<DxGridDataColumn FieldName="Id" SortIndex="0" SortOrder="Descending" ReadOnly />
|
||||||
|
<DxGridDataColumn FieldName="ShippingDate" Caption="Beérkezés" />
|
||||||
|
...
|
||||||
|
</Columns>
|
||||||
|
<DetailRowTemplate>
|
||||||
|
@{ var shipping = (Shipping)context.DataItem; }
|
||||||
|
<GridShippingDocument ParentDataItem="@shipping" ... />
|
||||||
|
</DetailRowTemplate>
|
||||||
|
</GridShippingBase>
|
||||||
|
</GridContent>
|
||||||
|
</MgGridWithInfoPanel>
|
||||||
|
```
|
||||||
|
|
||||||
## Key Architectural Decisions
|
## Key Architectural Decisions
|
||||||
|
|
||||||
- **nopCommerce plugin** — Customer, Order, Product are nopCommerce entities extended via GenericAttributes and DTOs
|
- **nopCommerce plugin** — Customer, Order, Product are nopCommerce entities extended via GenericAttributes and DTOs
|
||||||
- **SignalR over REST** — all data flows through SignalR with AcBinary protocol
|
- **SignalR over REST** — all data flows through SignalR with AcBinary protocol
|
||||||
- **DevExpress Blazor 25.1.3** — exclusive UI component library
|
- **DevExpress Blazor 25.1.3** — exclusive UI component library
|
||||||
|
- **MgGridBase** — canonical grid base from AyCode.Blazor for all data screens (SignalR CRUD, layout persistence, master-detail)
|
||||||
- **Three measurement hierarchies** — Shipping/Order/StockTaking share same base but have different audit rules
|
- **Three measurement hierarchies** — Shipping/Order/StockTaking share same base but have different audit rules
|
||||||
- **Client-side database** — `DatabaseClient` caches entities in ConcurrentDictionary for offline/fast access
|
- **Client-side database** — `DatabaseClient` caches entities in ConcurrentDictionary for offline/fast access
|
||||||
- **Platform-specific credential storage** — MAUI uses SecureStorage, Web uses obfuscated localStorage, Server uses no-op
|
- **Platform-specific credential storage** — MAUI uses SecureStorage, Web uses obfuscated localStorage, Server uses no-op
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,17 @@
|
||||||
# Conventions
|
# Conventions
|
||||||
|
|
||||||
|
> For core framework conventions see: `../../../Aycode/Source/AyCode.Core/docs/CONVENTIONS.md`
|
||||||
|
> For UI framework conventions see: `../../../Aycode/Source/AyCode.Blazor/docs/CONVENTIONS.md`
|
||||||
|
|
||||||
## Naming
|
## Naming
|
||||||
|
|
||||||
- **fb prefix** on database tables: `fbPallet`, `fbShipping`, `fbShippingItem`, etc.
|
- **fb prefix** on database tables: `fbPallet`, `fbShipping`, `fbShippingItem`, etc.
|
||||||
- **Dto suffix** for DTOs wrapping nopCommerce entities: `OrderDto`, `OrderItemDto`, `ProductDto`.
|
- **Dto suffix** for DTOs wrapping nopCommerce entities: `OrderDto`, `OrderItemDto`, `ProductDto`.
|
||||||
- **XxxItemPallet** for measurement records: `ShippingItemPallet`, `OrderItemPallet`, `StockTakingItemPallet`.
|
- **XxxItemPallet** for measurement records: `ShippingItemPallet`, `OrderItemPallet`, `StockTakingItemPallet`.
|
||||||
- **Grid prefix** for Blazor grid components: `GridPartnerBase`, `GridShippingBase`, etc.
|
- **Grid prefix** for Blazor grid components: `GridPartnerBase`, `GridShippingBase`, etc.
|
||||||
|
- **GridXxxBase** = C# code-behind class inheriting `FruitBankGridBase<TDataItem>`.
|
||||||
|
- **GridXxx.razor** = Razor markup using `<GridXxxBase>` with `<Columns>` and `<DetailRowTemplate>`.
|
||||||
|
- **OnGrid prefix** for MgGridBase event parameters: `OnGridItemDeleting`, `OnGridEditModelSaving`, `OnGridFocusedRowChanged`, etc. (avoids collision with DxGrid base events).
|
||||||
- **SignalRTags** constants use numeric ranges by domain (see `FruitBank.Common/SignalRs/`).
|
- **SignalRTags** constants use numeric ranges by domain (see `FruitBank.Common/SignalRs/`).
|
||||||
|
|
||||||
## Patterns
|
## Patterns
|
||||||
|
|
@ -14,10 +20,27 @@
|
||||||
- **GenericAttributes** for extending nopCommerce entities with custom data (IsMeasurable, Tare, AverageWeight).
|
- **GenericAttributes** for extending nopCommerce entities with custom data (IsMeasurable, Tare, AverageWeight).
|
||||||
- **Composition interfaces** for measurement traits: IMeasuringValues = IMeasuringWeights + IMeasuringQuantity.
|
- **Composition interfaces** for measurement traits: IMeasuringValues = IMeasuringWeights + IMeasuringQuantity.
|
||||||
- **DevExpress DxGrid** with `AcSignalRDataSource` for real-time grid data.
|
- **DevExpress DxGrid** with `AcSignalRDataSource` for real-time grid data.
|
||||||
- **MgGridBase** for grid layout persistence via localStorage.
|
- **MgGridBase** — canonical grid base from AyCode.Blazor (see [MGGRID.md](../../../Aycode/Source/AyCode.Blazor/docs/MGGRID.md)). Provides SignalR CRUD, layout persistence, master-detail, InfoPanel, fullscreen.
|
||||||
|
- **FruitBankGridBase** — project adapter that fixes `TId=int`, `TLoggerClient=LoggerClient`, adds per-user layout and master/detail defaults.
|
||||||
- **FruitBankSignalRClient** as single hub client for all server communication.
|
- **FruitBankSignalRClient** as single hub client for all server communication.
|
||||||
- **DatabaseClient** for client-side caching with ConcurrentDictionary tables.
|
- **DatabaseClient** for client-side caching with ConcurrentDictionary tables.
|
||||||
|
|
||||||
|
### Grid Creation Checklist
|
||||||
|
|
||||||
|
1. Create `GridXxxBase.cs` inheriting `FruitBankGridBase<TEntity>`.
|
||||||
|
2. Set CRUD tags in constructor: `GetAllMessageTag`, `AddMessageTag`, `UpdateMessageTag`, `RemoveMessageTag`.
|
||||||
|
3. Create `GridXxx.razor` with `<GridXxxBase>`, `<Columns>`, optional `<DetailRowTemplate>`.
|
||||||
|
4. Wrap in `<MgGridWithInfoPanel>` if InfoPanel is needed.
|
||||||
|
5. For detail grids: set `ParentDataItem`, `KeyFieldNameToParentId`, `ContextIds`.
|
||||||
|
|
||||||
|
### Grid Layout Storage Keys
|
||||||
|
|
||||||
|
```
|
||||||
|
{AutoSaveLayoutName}_{Master|ParentTypeName}_{AutoSave|UserSave}_{UserId}
|
||||||
|
```
|
||||||
|
|
||||||
|
Example: `GridShipping_Master_AutoSave_42` — auto-saved layout for shipping master grid, user #42.
|
||||||
|
|
||||||
## Code Reuse
|
## Code Reuse
|
||||||
|
|
||||||
- Before writing new code, search the codebase for existing implementations.
|
- Before writing new code, search the codebase for existing implementations.
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
# Glossary / Fogalomtár
|
# Glossary / Fogalomtár
|
||||||
|
|
||||||
|
> For core framework glossary see: `../../../Aycode/Source/AyCode.Core/docs/GLOSSARY.md`
|
||||||
|
> For UI framework glossary see: `../../../Aycode/Source/AyCode.Blazor/docs/GLOSSARY.md`
|
||||||
|
|
||||||
Domain terminology for the FruitBank system. **Read this before making changes.**
|
Domain terminology for the FruitBank system. **Read this before making changes.**
|
||||||
|
|
||||||
## Business Domain
|
## Business Domain
|
||||||
|
|
@ -58,3 +61,19 @@ FruitBank extends them via:
|
||||||
| IsMeasurable=false means no Pallet | ❌ Pallet is always created, weights just = 0.0 |
|
| IsMeasurable=false means no Pallet | ❌ Pallet is always created, weights just = 0.0 |
|
||||||
| NetWeight is stored | ❌ It's calculated: GrossWeight − PalletWeight − (TrayQuantity × TareWeight) |
|
| NetWeight is stored | ❌ It's calculated: GrossWeight − PalletWeight − (TrayQuantity × TareWeight) |
|
||||||
| GenericAttribute is simple | ❌ It's polymorphic: KeyGroup determines which entity type owns the record |
|
| GenericAttribute is simple | ❌ It's polymorphic: KeyGroup determines which entity type owns the record |
|
||||||
|
|
||||||
|
## UI / Grid Components
|
||||||
|
|
||||||
|
| Term | Definition |
|
||||||
|
|---|---|
|
||||||
|
| **MgGridBase** | Abstract generic grid component from AyCode.Blazor. Extends DevExpress `DxGrid` with SignalR CRUD, layout persistence, master-detail, InfoPanel. See [AyCode.Blazor/docs/MGGRID.md](../../../Aycode/Source/AyCode.Blazor/docs/MGGRID.md). |
|
||||||
|
| **FruitBankGridBase** | Project-level adapter: fixes `TSignalRDataSource=SignalRDataSourceObservable`, `TId=int`, `TLoggerClient=LoggerClient`. Adds per-user layout, master/detail defaults. |
|
||||||
|
| **MgGridWithInfoPanel** | `DxSplitter` wrapper: grid (left pane) + InfoPanel (right pane), fullscreen overlay, splitter size persistence. |
|
||||||
|
| **MgGridToolbarBase** | `DxToolbar` base with `Grid` (IMgGridBase) reference and `RefreshClick` callback. |
|
||||||
|
| **MgGridDataColumn** | Extended `DxGridDataColumn` with URL template support (`{PropertyName}` placeholders in links). |
|
||||||
|
| **MgGridInfoPanel** | Default InfoPanel showing column-value pairs for the focused row, supports edit mode. |
|
||||||
|
| **IMgGridBase** | Public interface for grid: `IsSyncing`, `GridEditState`, `ParentGrid`, `StepPrevRow/NextRow`, layout persistence methods. |
|
||||||
|
| **MgGridEditState** | Enum: `None` (no edit), `New` (adding item), `Edit` (modifying item). |
|
||||||
|
| **AutoSaveLayoutName** | Base name for localStorage layout keys. Default: `"Grid{TDataItem.Name}"`. |
|
||||||
|
| **SignalRCrudTags** | Bundle of 5 integer message tags (GetAll, GetItem, Add, Update, Remove) for one entity type. |
|
||||||
|
| **IsMasterGrid** | `true` when `ParentDataItem == null` — the grid is a top-level (not detail) grid. |
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue