### 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.0enableenable
```
--------------------------------
### 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 (
);
};
```
--------------------------------
### 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 (
);
};
```
--------------------------------
### 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 (
<>
>
);
};
```
--------------------------------
### 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");
}
}
```