### Basic MongoDB Setup Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/backend/mongodb.md Demonstrates the basic setup of Cratis MongoDB integration with WebApplicationBuilder. This configures default serializers and registers services. ```csharp var builder = WebApplication.CreateBuilder(args) .UseCratisApplicationModel(); builder.UseCratisMongoDB(); ``` -------------------------------- ### Directory.Build.props Example Source: https://github.com/cratis/applicationmodel/blob/main/README.md Demonstrates the use of Directory.Build.props files for setting common build settings across multiple projects in a .NET solution. ```xml net8.0 enable enable ``` -------------------------------- ### TypeScript Command Execution Example Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/frontend/react/commands.md Example demonstrating how to instantiate and execute a generated command in TypeScript. It shows setting command properties and awaiting the execution result. ```typescript const command = new OpenDebitAccount(); command.accountId = 'a23edccc-6cb5-44fd-a7a7-7563716fb080'; command.name = 'My Account'; command.owner = '84cda809-9201-4d8c-8589-0be37c6e3f18'; const result = await command.execute(); ``` -------------------------------- ### Example Base64 Output from Terminal Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/general/generating-principal.md The resulting base64 encoded string from the terminal command example. This output can be used for the 'x-ms-client-principal' header. ```text eyJjbGFpbXMiOlt7InR5cCI6InNvY2lhbG5vIiwidmFsIjoiMTIzNDU2ODc5MCJ9Cg== ``` -------------------------------- ### MongoDB Naming Policy Configuration Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/backend/mongodb.md Shows how to configure custom naming policies for MongoDB collections and members. Includes examples for using a custom policy class and a built-in camel case policy. ```csharp builder.UseCratisMongoDB(configureMongoDB: builder => builder.WithNamingPolicy()); ``` ```csharp builder.UseCratisMongoDB(configureMongoDB: builder => builder.WithNamingPolicy(new MyCustomNamingPolicy(...))); ``` ```csharp builder.UseCratisMongoDB(configureMongoDB: builder => builder.WithCamelCaseNamingPolicy()); ``` -------------------------------- ### Directory.Packages.props Example Source: https://github.com/cratis/applicationmodel/blob/main/README.md Illustrates the use of Central Package Management in .NET projects, where package versions are managed centrally in a Directory.Packages.props file. ```xml ``` -------------------------------- ### React General Support Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/frontend/index.md Provides general support and documentation for using React within the Cratis application model. This includes setup, best practices, and core concepts. ```React import React from 'react'; function App() { return (

Welcome to Cratis React App

); } ``` -------------------------------- ### Example Project Folder Structure Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/frontend/react/proxy-generation.md Illustrates a typical project folder structure with vertical slices for features, showing how namespaces might be organized across different tiers like Api, Domain, Events, and Read. ```shell | ├-- Api | └-- MyFeature ├-- Domain | └-- MyFeature ├-- Events | └-- MyFeature └-- Read └-- MyFeature ``` -------------------------------- ### C# Controller Action for Debit Account Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/frontend/react/commands.md Example of a C# controller action that handles a POST request for opening a debit account. It takes an 'OpenDebitAccount' command as input and appends a 'DebitAccountOpened' event. ```csharp using Microsoft.AspNetCore.Mvc; using System.Threading.Tasks; [ApiController] [Route("/api/accounts/debit")] public class DebitAccountController : ControllerBase { private readonly IEventLog _eventLog; public DebitAccountController(IEventLog eventLog) { _eventLog = eventLog; } [HttpPost] public Task OpenDebitAccount([FromBody] OpenDebitAccount create) => _eventLog.Append(create.AccountId, new DebitAccountOpened(create.Name, create.Owner)); } public record OpenDebitAccount(AccountId AccountId, AccountName Name, CustomerId Owner); ``` -------------------------------- ### React Application Model Configuration Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/frontend/react/index.md Guides on configuring the use of the Application Model within a React application. This involves setting up the necessary providers and context to enable Cratis features. ```React import { ApplicationModelProvider } from '@cratis/react'; function App() { return ( {/* Your application components */} ); } ``` -------------------------------- ### Implement IProvideIdentityDetails Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/backend/identity.md An example implementation of the `IProvideIdentityDetails` interface to provide custom identity details and authorization status for a user. This implementation is discovered and called automatically by the Cratis framework. ```csharp public class IdentityDetailsProvider : IProvideIdentityDetails { public Task Provide(IdentityProviderContext context) { var result = new IdentityDetails(true, new { Hello = "World" }); return Task.FromResult(result); } } ``` -------------------------------- ### Command Proxy Generation Example Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/frontend/react/proxy-generation.md Demonstrates how a C# controller action for a command is transformed into a frontend command proxy. The generated proxy inherits from `Command` and flattens all parameters (route, query, body) into properties. ```csharp using Microsoft.AspNetCore.Mvc; using System.Threading.Tasks; [Route("/api/accounts/debit")] public class DebitAccounts : Controller { readonly IEventLog _eventLog; public DebitAccounts(IEventLog eventLog) => _eventLog = eventLog; [HttpPost] public Task OpenDebitAccount([FromBody] OpenDebitAccount create) { // Do things... return Task.CompletedTask; } } public class OpenDebitAccount { // Properties derived from arguments or body } ``` ```typescript // Generated TypeScript proxy for OpenDebitAccount // import { Command } from '@cratis/applications/commands'; // class OpenDebitAccountCommand /* extends Command */ { // // Properties derived from C# controller arguments and body // } ``` -------------------------------- ### Query Proxy Generation Example Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/frontend/react/proxy-generation.md Shows how a C# controller action for a query is converted into a frontend query proxy. The generated proxy will represent the data retrieval operation, including handling of return types. ```csharp using Microsoft.AspNetCore.Mvc; using System.Collections.Generic; public class DebitAccount { // Properties of a DebitAccount } [Route("/api/accounts")] public class AccountsController : Controller { [HttpGet] public IEnumerable AllAccounts() { // Get data and return return new List(); } } ``` ```typescript // Generated TypeScript proxy for AllAccounts query // import { QueryResultWithState } from '@cratis/applications'; // interface DebitAccount { // // Properties of a DebitAccount // } // const useAllAccounts = (): QueryResultWithState => { // // React hook implementation to fetch data // return { data: [], isLoading: false, isPerforming: false }; // }; ``` -------------------------------- ### Busy Indicator Dialog Example Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/frontend/react.mvvm/dialogs.md Illustrates how to display a busy indicator dialog using the IDialogs service from a ViewModel. The example shows how to open the dialog and then close it after a delay. ```ts import { injectable } from 'tsyringe'; import { DialogResult } from '@cratis/applications.react/dialogs'; import { DialogButtons, IDialogs } from '@cratis/applications.react.mvvm/dialogs'; @injectable() export class YourViewModel { constructor( private readonly _dialogs: IDialogs) { } // Method called from typically your view async performLongRunningOperation() { const busyIndicator = this._dialogs.showBusyIndicator('Performing something that will take a while', 'Please wait'); setTimeout(() => { busyIndicator.close(); }, 1000); } } ``` -------------------------------- ### Confirmation Dialog Example Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/frontend/react.mvvm/dialogs.md Demonstrates how to use the IDialogs service to show a confirmation dialog with 'Yes' and 'No' buttons from a ViewModel. It handles the user's response to perform an action. ```ts import { injectable } from 'tsyringe'; import { DialogResult } from '@cratis/applications.react/dialogs'; import { DialogButtons, IDialogs } from '@cratis/applications.react.mvvm/dialogs'; @injectable() export class YourViewModel { constructor( private readonly _dialogs: IDialogs) { } // Method called from typically your view async deleteTheThing() { const result = await this._dialogs.showConfirmation('Delete?', 'Are you sure you want to delete?', DialogButtons.YesNo); if( result == DialogResult.Yes ) { // Do something - typically call your server } } } ``` -------------------------------- ### Include MVVM Context in Application Setup Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/frontend/react.mvvm/mvvm-context.md This snippet demonstrates how to include the MVVM component in your React application's setup. The MVVM component configures MobX and Tsyringe, ensuring the necessary bindings for the Cratis Application Model to function correctly. ```tsx import { MVVM } from '@cratis/applications.react.mvvm'; export const App = () => { return ( {/* Your application */} ); }; ``` -------------------------------- ### Using Dialogs with View Models Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/frontend/react.mvvm/dialogs.md Demonstrates how to use dialogs with view models in Cratis applications. It shows the setup with TSyringe, the dialog request class, the React component using `withViewModel`, and the view model implementation. ```javascript if( result == 'Done done done...') { // Do something } } ``` ```ts import { inject, injectable } from 'tsyringe'; import { DialogContextContent, DialogResult } from '@cratis/applications.react/dialogs'; @injectable() export class CustomDialogViewModel { constructor(private readonly _dialogContext: DialogContextContent) { } name: string = ''; done() { this._dialogContext.closeDialog(DialogResult.Ok, 'Done done done...'); } cancel() { this._dialogContext.closeDialog(DialogResult.Cancelled, 'Did not do it..'); } } ``` ```tsx import { Button } from 'primereact/button'; import { Dialog } from 'primereact/dialog'; import { useDialogContext, CloseDialog } from '@cratis.applications.react/dialogs'; import { withViewModel } from '@cratis.applications.react.mvvm'; import { CustomDialogViewModel } from './CustomDialogViewModel'; export class CustomDialogRequest { constructor(readonly content: string) { } } // Use the withViewModel() to pull in and specify props export const CustomDialog = withViewModel({ viewModel }) => { return ( viewModel.cancel() }>

Dialog

{request.content}
); }; ``` -------------------------------- ### Accessing Identity with useIdentity() Hook Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/frontend/react/identity.md Provides an example of using the `useIdentity()` hook to easily access identity details within functional React components. ```typescript import { useIdentity } from '@cratis/applications.react/identity'; export const Home = () => { const identity = useIdentity(); return (

User: {identity.details.firstName} {identity.details.lastName}

); }; ``` -------------------------------- ### Initializing reflect-metadata and Application Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/frontend/react.mvvm/tsyringe.md Imports the 'reflect-metadata' package to enable reflection capabilities and renders the main 'App' component within a React StrictMode context. This setup is crucial for Tsyringe's runtime dependency resolution. ```typescript import 'reflect-metadata'; import { App } from './App'; ReactDOM.createRoot(document.getElementById('root')!).render( ); ``` -------------------------------- ### Command Usage in a Component Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/frontend/react/command-scope.md Example of how a component can utilize a command (e.g., `MyCommand`) and bind its properties to UI elements like input fields. Changes to these properties are tracked by the CommandScope. ```typescript export const FirstComponent = () => { const myCommand = MyCommand.use(); return (
myCommand.someValue = v; }/>
) } ``` -------------------------------- ### Simplified Observable Query with .Observe() Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/backend/queries.md Demonstrates a simplified way to create observable queries using the .Observe() extension method, reducing boilerplate code. ```csharp public class Accounts : Controller { readonly IMongoCollection _collection; public Accounts(IMongoCollection collection) => _collection = collection; [HttpGet] public ISubject> AllAccounts() { return _accountsCollection.Observe(); // <- } } ``` -------------------------------- ### Conditional Validation for Commands (Basic) Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/backend/validation.md Applies validation rules specifically when the operation is a command. This example shows a rule that is always applied and another that is only applied when it's a command. ```csharp using Cratis.Applications.Validation; public class UserIdValidator : ConceptValidator { public UserIdValidator() { RuleFor(userId => userId) .NotNull() .UserMustExist().WithMessage("User does not exist."); RuleFor(userId => userId) .UserMustNotBeSystem().WithMessage("Operation is not allowed on a system user.") .WhenCommand(); } } ``` -------------------------------- ### Setting up IdentityProvider Context Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/frontend/react/identity.md Demonstrates how to wrap the application with the IdentityProvider at the top level to make identity services available throughout the application. ```typescript import { IdentityProvider } from '@cratis/applications.react/identity'; export const App = () => { return ( {/* ... your app content ... */} ); }; ``` -------------------------------- ### Get Current Identity Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/frontend/core/identity.md Retrieves the current user's identity information. This is an asynchronous operation that may call a backend endpoint if the identity cookie is not found. ```typescript import { IdentityProvider } from '@cratis/applications/identity'; const identity = await IdentityProvider.getCurrent(); console.log(`Hello '${identity.name}'`); ``` -------------------------------- ### Get Identity with Custom Details Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/frontend/core/identity.md Retrieves the current user's identity information, specifying a custom type for the 'details' property. This allows for application-specific identity data. ```typescript import { IdentityProvider } from '@cratis/applications/identity'; type IdentityDetails = { department: string, age: number }; const identity = await IdentityProvider.getCurrent(); console.log(`Hello '${identity.name}' from ´${identity.details.department}`); ``` -------------------------------- ### Commands in React Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/frontend/react/index.md Understand the concept of commands and how to execute them within your React application using the Cratis Application Model. This includes defining commands and handling their execution. ```React import { useCommands } from '@cratis/react'; function SaveButton() { const commands = useCommands(); const handleSave = () => { commands.execute('SaveItem', { id: 1, name: 'New Name' }); }; return ( ); } ``` -------------------------------- ### Using the React Hook with Initial Values Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/frontend/react/commands.md Illustrates how to provide initial values directly to the React hook when integrating Cratis commands. This allows the hook to manage the command's state and track changes from the outset. ```typescript export const MyComponent = () => { const [openDebitAccount] = OpenDebitAccount.use({ accountId: 'a23edccc-6cb5-44fd-a7a7-7563716fb080'; name: 'My Account'; owner: '84cda809-9201-4d8c-8589-0be37c6e3f18'; }); return ( <> ) }; ``` -------------------------------- ### Initialize MVVM Bindings Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/frontend/react.mvvm/tsyringe.md Initializes the bindings for the React MVVM package by calling the `initialize` method on the `Bindings` service. This is typically done in view models to set up MVVM-related functionalities. Note that this step can be skipped if using the MVVM context, as bindings are automatically configured. ```typescript import { Bindings } from '@cratis/applications.react.mvvm'; Bindings.initialize(); ``` -------------------------------- ### Defining a Custom Busy Indicator Dialog Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/frontend/react/dialogs.md An example of defining a custom busy indicator dialog component using Prime React. It utilizes `useDialogContext` to access the dialog request and displays a `ProgressSpinner`. ```tsx import { Dialog } from 'primereact/dialog'; import { BusyIndicatorDialogRequest, useDialogContext } from '@cratis/applications.react/dialogs'; import { ProgressSpinner } from 'primereact/progressspinner'; export const BusyIndicatorDialog = () => { const { request } = useDialogContext(); const headerElement = (
{request.title}
); return ( <> { }}>

{request.message}

); }; ``` -------------------------------- ### Setting Initial Values on a Command Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/frontend/react/commands.md Demonstrates how to instantiate a command and set its initial values for change tracking. The `hasChanges` property will reflect modifications from these initial values. ```typescript const command = new CreateDebitCommand(); command.setInitialValues({ accountId: 'a23edccc-6cb5-44fd-a7a7-7563716fb080'; name: 'My Account'; owner: '84cda809-9201-4d8c-8589-0be37c6e3f18'; }); // At this stage `hasChanges` will be returning `false`. // If we alter something like name: command.name = 'My other account'; // `hasChanges` will now be `true`. ``` -------------------------------- ### Accounts Controller with Filtering Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/backend/queries.md An Accounts controller that supports filtering accounts by name using a regex pattern. It demonstrates handling query parameters. ```csharp public class Accounts : Controller { readonly IMongoCollection _collection; public Accounts(IMongoCollection collection) => _collection = collection; [HttpGet("starting-with")] public async Task> StartingWith([FromQuery] string? filter) { var filterDocument = Builders .Filter .Regex("name", $"^{filter ?? string.Empty}.*"); var result = await _accountsCollection.FindAsync(filterDocument); return result.ToList(); } } ``` -------------------------------- ### Proxy Generation for C# to TypeScript Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/backend/queries.md Information about the proxy generator tool that automatically creates TypeScript code from C# query definitions for frontend use. ```typescript // Proxy generation automatically creates TypeScript code from C# query definitions. // See ../frontend/cqrs/proxy-generation.md for more details. ``` -------------------------------- ### Package Scripts in package.json Source: https://github.com/cratis/applicationmodel/blob/main/README.md Defines scripts for package management and build processes, leveraging global scripts defined in the root package.json. These scripts facilitate common tasks like building, cleaning, linting, and testing. ```json { "scripts": { "prepublish": "yarn g:build", "clean": "yarn g:clean", "build": "yarn g:build", "lint": "yarn g:lint", "lint:ci": "yarn g:lint:ci", "test": "yarn g:test", "ci": "yarn g:ci", "up": "yarn g:up" } } ``` -------------------------------- ### Using useQuery Hook in React Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/frontend/react/queries.md Demonstrates how to use the `useQuery` hook from the Cratis application model within a React component to fetch data. It shows the basic invocation and the returned tuple. ```typescript export const MyComponent = () => { const [accounts, queryAccounts] = AllAccounts.use(); return ( <> ) }; ``` -------------------------------- ### Command Usage in Another Component Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/frontend/react/command-scope.md Similar to the `FirstComponent`, this example shows another component (`SecondComponent`) using a different command (`MyOtherCommand`) and binding its properties to an input field. Changes are also tracked by the CommandScope. ```typescript export const SecondComponent = () => { const myCommand = MyOtherCommand.use(); return (
myCommand.someValue = v; }/>
) } ``` -------------------------------- ### Queries in React Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/frontend/react/index.md Learn how to define and execute queries in your React application using the Cratis Application Model. This covers fetching data and handling query results. ```React import { useQueries } from '@cratis/react'; function ItemList() { const queries = useQueries(); const items = queries.execute('GetAllItems'); return (
    {items.map(item =>
  • {item.name}
  • )}
); } ``` -------------------------------- ### Initialize Application Model Context Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/frontend/react/application-model.md Demonstrates how to integrate the ApplicationModel component into a React application to provide the microservice context. This component configures other application model contexts and ensures correct request handling in a microservice environment. ```tsx export const App = () => { return ( {/* Your application */} ); }; ``` -------------------------------- ### Configure Cratis Proxy Output Folder Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/frontend/react/proxy-generation.md Specifies the output directory for generated Cratis proxies within a .csproj file. This helps maintain the folder structure based on namespaces. ```xml $(MSBuildThisFileDirectory)../Web ``` -------------------------------- ### Basic Accounts Controller Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/backend/queries.md A simple controller for managing DebitAccount objects. It retrieves all accounts from a MongoDB collection. ```csharp public class Accounts : Controller { readonly IMongoCollection _collection; public Accounts(IMongoCollection collection) => _collection = collection; [HttpGet] public IEnumerable AllAccounts() => _collection.Find(_ => true).ToList(); } ``` -------------------------------- ### Command Proxy Generation with Route Parameters Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/frontend/react/proxy-generation.md Illustrates command proxy generation when route parameters are used. The generated TypeScript command object will include properties for `accountId` and `amount` derived from the route. ```csharp using Microsoft.AspNetCore.Mvc; using System.Threading.Tasks; [Route("/api/accounts/debit/{accountId}")] public class DebitAccount : Controller { readonly IEventLog _eventLog; public DebitAccount(IEventLog eventLog) => _eventLog = eventLog; [HttpPost("deposit/{amount}")] public Task DepositToAccount([FromRoute] AccountId accountId, [FromRoute] double amount) { // Do things return Task.CompletedTask; } } public class AccountId { // Properties for accountId } ``` ```typescript // Generated TypeScript proxy for DepositToAccount command // import { Command } from '@cratis/applications/commands'; // class DepositToAccountCommand /* extends Command */ { // accountId: string; // or appropriate type // amount: number; // } ``` -------------------------------- ### MVVM for React Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/frontend/index.md Details the specific implementation and usage of the Model-View-ViewModel (MVVM) architectural pattern for React applications within the Cratis framework. Covers data binding, state management, and component interaction. ```React import React, { useState, useEffect } from 'react'; // ViewModel class CounterViewModel { constructor() { this.count = 0; } increment() { this.count++; } getCount() { return this.count; } } // View function CounterView() { const [viewModel] = useState(new CounterViewModel()); const [displayCount, setDisplayCount] = useState(0); useEffect(() => { setDisplayCount(viewModel.getCount()); }, [viewModel]); const handleIncrement = () => { viewModel.increment(); setDisplayCount(viewModel.getCount()); }; return (

Counter: {displayCount}

); } export default CounterView; ``` -------------------------------- ### TypeScript Command Proxy for OpenDebitAccount Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/frontend/react/commands.md Generated TypeScript representation of the 'OpenDebitAccount' command, including interface, validator, and command class. It defines the command's route, properties, and validation rules for frontend use. ```typescript import { Command, CommandValidator, CommandPropertyValidators, useCommand, SetCommandValues } from '@cratis/applications/commands'; import { Validator } from '@cratis/applications/validation'; import Handlebars from 'handlebars'; const routeTemplate = Handlebars.compile('/api/accounts/debit'); export interface IOpenDebitAccount { accountId?: string; name?: string; owner?: string; } export class OpenDebitAccountValidator extends CommandValidator { readonly properties: CommandPropertyValidators = { accountId: new Validator(), name: new Validator(), owner: new Validator(), }; } export class OpenDebitAccount extends Command implements IOpenDebitAccount { readonly route: string = '/api/accounts/debit'; readonly routeTemplate: Handlebars.TemplateDelegate = routeTemplate; readonly validation: CommandValidator = new OpenDebitAccountValidator(); private _accountId!: string; private _name!: string; private _owner!: string; get requestArguments(): string[] { return [ ]; } get properties(): string[] { return [ 'accountId', 'name', 'owner', ]; } get accountId(): string { return this._accountId; } set accountId(value: string) { this._accountId = value; this.propertyChanged('accountId'); } get name(): string { return this._name; } set name(value: string) { this._name = value; this.propertyChanged('name'); } get owner(): string { return this._owner; } set owner(value: string) { this._owner = value; this.propertyChanged('owner'); } static use(initialValues?: IOpenDebitAccount): [OpenDebitAccount, SetCommandValues] { return useCommand(OpenDebitAccount, initialValues); } } ``` -------------------------------- ### Observable Accounts Controller with MongoDB Watch API Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/backend/queries.md Implements an observable query for accounts using MongoDB's Watch API and Cratis' ClientObservable. It pushes changes to connected clients via WebSockets. ```csharp public class Accounts : Controller { readonly IMongoCollection _collection; public Accounts(IMongoCollection collection) => _collection = collection; [HttpGet] public ISubject> AllAccounts() { var observable = new ClientObservable> (); var accounts = _accountsCollection.Find(_ => true).ToList(); observable.OnNext(accounts); var cursor = _accountsCollection.Watch(); Task.Run(() => { while (cursor.MoveNext()) { if (!cursor.Current.Any()) continue; observable.OnNext(_accountsCollection.Find(_ => true).ToList()); } }); observable.ClientDisconnected = () => cursor.Dispose(); return observable; } } ``` -------------------------------- ### Generate Base64 Encoded Principal via Terminal Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/general/generating-principal.md Demonstrates how to generate a base64 encoded string from a JSON payload using the 'echo' and 'base64' commands in a Unix-like terminal. This is an alternative method for creating the client principal header value. ```shell echo "{\"claims\":[{\"typ\":\"socialno\",\"val\":\"1234568790\"}" |base64 ``` -------------------------------- ### Handling Dialogs in React Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/frontend/react/index.md This section explains how to implement and manage dialogs in a consistent manner using the Cratis Application Model in React. It covers opening, closing, and passing data to dialogs. ```React import { useDialogs } from '@cratis/react'; function MyComponent() { const dialogs = useDialogs(); const openConfirmationDialog = () => { dialogs.open('ConfirmationDialog', { message: 'Are you sure?' }); }; return ( ); } ``` -------------------------------- ### Handling Props with IHandleProps Interface Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/frontend/react.mvvm/using-view-model.md Demonstrates implementing the `IHandleProps` interface to manage prop changes within a view model. The `handleProps` method is called automatically on initial load and whenever props are updated, allowing for dynamic updates based on prop values. ```ts import { IHandleProps } from '@cratis/applications.react.mvvm'; export class MyViewModel implements IHandleProps { handleProps(props: Props): void { // Do things based on props } } ``` -------------------------------- ### Query Parameters with FromQuery Attribute Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/frontend/react/queries.md Illustrates how C# query methods with the `[FromQuery]` attribute are translated into parameters for the React frontend hooks. Shows both the C# backend definition and the TypeScript usage. ```csharp [HttpGet("starting-with")] public IEnumerable StartingWith([FromQuery] string? filter) { var filterDocument = Builders .Filter .Regex("name", $"^{filter ?? string.Empty}.*"); return _collection.Find(filterDocument).ToList(); } ``` ```typescript export const MyComponent = () => { const [accounts, queryAccounts] = StartingWith.use({ filter: '' }); return ( <> ) }; ``` -------------------------------- ### Define a Debit Account Model Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/backend/queries.md Defines a DebitAccount record with properties for Id, Name, Owner, and Balance. This model uses value type encapsulation for clearer APIs. ```csharp public record DebitAccount(AccountId Id, AccountName Name, CustomerId Owner, double Balance); ``` -------------------------------- ### Client Principal JSON Structure Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/general/generating-principal.md Defines the expected JSON structure for the client principal, including identity provider, user ID, user details, roles, and custom claims. This structure is used to simulate user authentication and authorization. ```json { "identityProvider": "aad", "userId": "e7f664ca-4ecc-45be-84cf-74b6240d049a", "userDetails": "jane@doe.io", "userRoles": ["anonymous", "authenticated"], "claims": [{ "typ": "socialno", "val": "12345678901" }, { "typ": "surname", "val": "Doe" }, { "typ": "givenname", "val": "Jane" }] } ``` -------------------------------- ### Working with Identity in React Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/frontend/react/index.md Learn how to manage user identity and authentication within your React application using the Cratis Application Model. This includes handling login, logout, and accessing user information. ```React import { useIdentity } from '@cratis/react'; function UserProfile() { const identity = useIdentity(); return (
{identity.isAuthenticated ? (

Welcome, {identity.name}!

) : (

Please log in.

)}
); } ``` -------------------------------- ### Handling Route Params with IHandleParams Interface Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/frontend/react.mvvm/using-view-model.md Explains how to implement the `IHandleParams` interface to react to changes in route parameters. The `handleParams` method is invoked on component mount and whenever route parameters are updated, enabling dynamic behavior based on URL segments. ```ts import { IHandleParams } from '@cratis/applications.react.mvvm'; export class MyViewModel implements IHandleParams { handleParams(params: Params): void { // Do things based on params } } ``` -------------------------------- ### .NET Proxy Generation for React Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/frontend/react/index.md Information about the .NET proxy generator and its role in facilitating communication between your React frontend and the Cratis backend. This simplifies API interactions. ```csharp // Example of a generated C# proxy class public class ItemServiceProxy : IItemService { private readonly IHttpClient _httpClient; public ItemServiceProxy(IHttpClient httpClient) { _httpClient = httpClient; } public async Task> GetAllItemsAsync() { return await _httpClient.GetAsync>("/api/items"); } } ``` -------------------------------- ### Enable Authentication and Authorization Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/backend/identity.md Enables the default authentication and authorization middleware for the application pipeline. This is crucial for the identity handling to take effect. ```csharp var app = builder.Build(); app.UseAuthentication(); app.UseAuthorization(); ``` -------------------------------- ### Using useBusyIndicator Hook with Initial Definition Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/frontend/react/dialogs.md Demonstrates how to use the `useBusyIndicator` hook to show and close a busy indicator dialog. The dialog's title and message are provided directly to the hook. ```tsx import { Button } from 'primereact/button'; import {useBusyIndicator } from '@cratis/applications.react/dialogs'; export const Feature = () => { const [showBusyIndicator, closeBusyIndicator] = useBusyIndicator('The title', 'The message'); return (
) } ``` -------------------------------- ### Handle Dynamic Query Params with IHandleQueryParams Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/frontend/react.mvvm/using-view-model.md Implements the IHandleQueryParams interface to react to changes in query parameters even when the component is not unloaded. The handleQueryParams method is called on initial load and for subsequent changes. The generic argument for the interface is optional, defaulting to 'object'. ```ts import { IHandleQueryParams } from '@cratis/applications.react.mvvm'; export class MyViewModel implements IHandleQueryParams { handleQueryParams(queryParams: QueryParams): void { // Do things based on query params } } ``` -------------------------------- ### Using CommandScope in a Composition Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/frontend/react/command-scope.md Demonstrates how to wrap components within CommandScope to enable command tracking and aggregation of changes. This sets up the React context for descendant components. ```typescript import { CommandScope } from '@cratis/applications/commands'; export const MyComposition = () => { return ( ); }; ``` -------------------------------- ### Fluent Validation for Concepts Source: https://github.com/cratis/applicationmodel/blob/main/Documentation/backend/validation.md Illustrates how to create a validator for a domain concept using FluentValidation. This allows for reusable validation logic that can be implicitly hooked into the validation pipeline. ```csharp using Cratis.Applications.Validation; public record AccountName(string Value) : ConceptAs(Value); public class AccountNameValidator : ConceptValidator { public AccountNameValidator() { RuleFor(_ => _).Length(0, 16).WithMessage("Account name has to be less than 16 characters"); } } ```