Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions Documentation/CommandDialog/advanced-features.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,84 @@
# CommandDialog - Advanced Features

## Response Type Handling

`CommandDialog` supports typed command responses and provides callbacks for different execution outcomes:

```typescript
import { CommandDialog } from '@cratis/components/CommandDialog';
import { ValidationResult } from '@cratis/arc/validation';

type CreateUserResponse = {
userId: string;
username: string;
message: string;
};

<CommandDialog<CreateUser, CreateUserResponse>
command={CreateUser}
title="Create User"
onSuccess={(response) => {
// Handle successful creation - response is fully typed
console.log(`User created with ID: ${response.userId}`);
showNotification(response.message);
navigate(`/users/${response.userId}`);
}}
onFailed={(commandResult) => {
// Handle any failure - includes all failure details
console.error('Command failed:', commandResult);
}}
onException={(messages, stackTrace) => {
// Handle exceptions specifically
console.error('Exception occurred:', messages.join(', '));
console.error('Stack trace:', stackTrace);
}}
onUnauthorized={() => {
// Handle authorization failures
showNotification('You are not authorized to perform this action');
navigate('/login');
}}
onValidationFailure={(validationResults) => {
// Handle validation failures
const errors = validationResults.map(r => r.message).join(', ');
showNotification(`Validation failed: ${errors}`);
}}
/>
```

### Callback Execution Order

Multiple callbacks may fire for the same command execution:

1. **onSuccess**: Only fires when `commandResult.isSuccess` is `true`
2. **onFailed**: Fires for any failure (validation, exception, unauthorized, etc.)
3. **onException**: Fires specifically when an exception occurs
4. **onUnauthorized**: Fires specifically when authorization fails
5. **onValidationFailure**: Fires specifically when validation fails

For example, a validation failure will trigger both `onFailed` and `onValidationFailure`.

### Response Type Inference

The response type parameter is optional and defaults to `object`:

```typescript
// Explicit response type
<CommandDialog<CreateUser, CreateUserResponse>
command={CreateUser}
onSuccess={(response) => {
// response is CreateUserResponse
}}
/>

// Default object response type
<CommandDialog<CreateUser>
command={CreateUser}
onSuccess={(response) => {
// response is object
}}
/>
```

## Field Validation

Provide custom validation logic for individual fields:
Expand Down
31 changes: 28 additions & 3 deletions Documentation/CommandDialog/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,17 @@ const CreateProjectDialog = () => {
const { closeDialog } = useDialogContext<CommandResult<CreateProjectResponse>>();

return (
<CommandDialog<CreateProject>
<CommandDialog<CreateProject, CreateProjectResponse>
command={CreateProject}
title='Create project'
okLabel='Create'
onConfirm={async () => closeDialog(DialogResult.Ok)}
onSuccess={(response) => {
console.log('Project created:', response.projectId);
closeDialog(DialogResult.Ok);
}}
onValidationFailure={(errors) => {
console.error('Validation failed:', errors);
}}
onCancel={() => closeDialog(DialogResult.Cancelled)}
/>
);
Expand All @@ -72,7 +78,7 @@ function MyComponent() {
}
```

> `CommandDialog` invokes `onConfirm` only when command execution succeeds.
> `CommandDialog` invokes `onSuccess` when command execution succeeds, and other callbacks based on the command result.

## Props

Expand All @@ -86,6 +92,11 @@ function MyComponent() {
- `visible`: Boolean controlling dialog visibility (defaults to `true`)
- `initialValues`: Initial values for the command form
- `currentValues`: Current values to populate the form
- `onSuccess`: Callback invoked on successful command execution with the typed response
- `onFailed`: Callback invoked when command execution fails with the full `CommandResult<TResponse>`
- `onException`: Callback invoked when the command throws an exception with error messages and stack trace
- `onUnauthorized`: Callback invoked when authorization fails
- `onValidationFailure`: Callback invoked on validation errors with the validation results
- `onConfirm`: Confirm callback from `Dialog` (called only after successful command execution)
- `onCancel`: Cancel callback from `Dialog`
- `onClose`: Fallback close callback from `Dialog`
Expand All @@ -104,6 +115,20 @@ function MyComponent() {

## Callback Behavior

### Result Callbacks

`CommandDialog` supports the following result callbacks that are invoked based on the command execution outcome:

- `onSuccess(response: TResponse)`: Invoked when the command executes successfully. Receives the typed response.
- `onFailed(commandResult: CommandResult<TResponse>)`: Invoked when command execution fails for any reason.
- `onException(messages: string[], stackTrace: string)`: Invoked when the command throws an exception.
- `onUnauthorized()`: Invoked when authorization fails.
- `onValidationFailure(validationResults: ValidationResult[])`: Invoked on validation errors.

Multiple callbacks may fire for the same execution. For example, both `onFailed` and `onValidationFailure` will be invoked for validation errors.

### Dialog Callbacks

- `onConfirm` is executed only after command execution succeeds.
- If `onConfirm` returns `true`, the dialog closes; otherwise it stays open.
- If `onConfirm` is not provided, `onClose(DialogResult.Ok)` is used.
Expand Down
88 changes: 88 additions & 0 deletions Documentation/StepperCommandDialog/advanced-features.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,94 @@

All advanced features described here apply to every step in the wizard, because all steps share a single underlying command instance.

## Response Type Handling

`StepperCommandDialog` supports typed command responses and provides callbacks for different execution outcomes:

```typescript
import { StepperCommandDialog } from '@cratis/components/CommandDialog';
import { StepperPanel } from 'primereact/stepperpanel';
import { ValidationResult } from '@cratis/arc/validation';

type CreateProjectResponse = {
projectId: string;
message: string;
};

<StepperCommandDialog<CreateProject, CreateProjectResponse>
command={CreateProject}
title="Create Project"
onSuccess={(response) => {
// Handle successful creation - response is fully typed
console.log(`Project created with ID: ${response.projectId}`);
showNotification(response.message);
navigate(`/projects/${response.projectId}`);
}}
onFailed={(commandResult) => {
// Handle any failure - includes all failure details
console.error('Command failed:', commandResult);
}}
onException={(messages, stackTrace) => {
// Handle exceptions specifically
console.error('Exception occurred:', messages.join(', '));
}}
onUnauthorized={() => {
// Handle authorization failures
showNotification('You are not authorized to perform this action');
}}
onValidationFailure={(validationResults) => {
// Handle validation failures
const errors = validationResults.map(r => r.message).join(', ');
showNotification(`Validation failed: ${errors}`);
}}
>
<StepperPanel header="Basic Info">
<InputTextField<CreateProject> value={c => c.name} title="Name" />
</StepperPanel>
<StepperPanel header="Details">
<TextAreaField<CreateProject> value={c => c.description} title="Description" />
</StepperPanel>
</StepperCommandDialog>
```

### Callback Execution Order

Multiple callbacks may fire for the same command execution:

1. **onSuccess**: Only fires when `commandResult.isSuccess` is `true`
2. **onFailed**: Fires for any failure (validation, exception, unauthorized, etc.)
3. **onException**: Fires specifically when an exception occurs
4. **onUnauthorized**: Fires specifically when authorization fails
5. **onValidationFailure**: Fires specifically when validation fails

For example, a validation failure will trigger both `onFailed` and `onValidationFailure`.

### Response Type Inference

The response type parameter is optional and defaults to `object`:

```typescript
// Explicit response type
<StepperCommandDialog<CreateProject, CreateProjectResponse>
command={CreateProject}
onSuccess={(response) => {
// response is CreateProjectResponse
}}
>
{/* steps */}
</StepperCommandDialog>

// Default object response type
<StepperCommandDialog<CreateProject>
command={CreateProject}
onSuccess={(response) => {
// response is object
}}
>
{/* steps */}
</StepperCommandDialog>
```

## Field Validation

Provide custom validation logic for individual fields:
Expand Down
43 changes: 40 additions & 3 deletions Documentation/StepperCommandDialog/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,25 @@ import { InputTextField, TextAreaField, NumberField } from '@cratis/components/C
import { CommandResult } from '@cratis/arc/commands';
import { DialogResult, useDialog, useDialogContext } from '@cratis/arc.react/dialogs';

type CreateProjectResponse = {
projectId: string;
};

const CreateProjectDialog = () => {
const { closeDialog } = useDialogContext<CommandResult<object>>();
const { closeDialog } = useDialogContext<CommandResult<CreateProjectResponse>>();

return (
<StepperCommandDialog<CreateProject>
<StepperCommandDialog<CreateProject, CreateProjectResponse>
command={CreateProject}
title="Create New Project"
okLabel="Create"
onConfirm={() => closeDialog(DialogResult.Ok)}
onSuccess={(response) => {
console.log('Project created:', response.projectId);
closeDialog(DialogResult.Ok);
}}
onValidationFailure={(errors) => {
console.error('Validation failed:', errors);
}}
onCancel={() => closeDialog(DialogResult.Cancelled)}
>
<StepperPanel header="Basic Info">
Expand Down Expand Up @@ -77,6 +87,11 @@ function MyComponent() {
- `visible`: Boolean controlling dialog visibility (defaults to `true`)
- `initialValues`: Initial values for the command form
- `currentValues`: Current values to populate the form
- `onSuccess`: Callback invoked on successful command execution with the typed response
- `onFailed`: Callback invoked when command execution fails with the full `CommandResult<TResponse>`
- `onException`: Callback invoked when the command throws an exception with error messages and stack trace
- `onUnauthorized`: Callback invoked when authorization fails
- `onValidationFailure`: Callback invoked on validation errors with the validation results
- `onConfirm`: Confirm callback — called only after successful command execution
- `onCancel`: Cancel callback — invoked when the X button is clicked
- `onClose`: Fallback close callback
Expand Down Expand Up @@ -106,6 +121,28 @@ All [PrimeReact Stepper](https://primereact.org/stepper/) customization props ar
- `ptOptions`: PassThrough configuration options
- `unstyled`: Removes built-in component styles

## Callback Behavior

### Result Callbacks

`StepperCommandDialog` supports the following result callbacks that are invoked based on the command execution outcome:

- `onSuccess(response: TResponse)`: Invoked when the command executes successfully. Receives the typed response.
- `onFailed(commandResult: CommandResult<TResponse>)`: Invoked when command execution fails for any reason.
- `onException(messages: string[], stackTrace: string)`: Invoked when the command throws an exception.
- `onUnauthorized()`: Invoked when authorization fails.
- `onValidationFailure(validationResults: ValidationResult[])`: Invoked on validation errors.

Multiple callbacks may fire for the same execution. For example, both `onFailed` and `onValidationFailure` will be invoked for validation errors.

### Dialog Callbacks

- `onConfirm` is executed only after command execution succeeds.
- If `onConfirm` returns `true`, the dialog closes; otherwise it stays open.
- If `onConfirm` is not provided, `onClose(DialogResult.Ok)` is used.
- `onCancel` follows the same behavior as `Dialog` (`true` closes).
- `onClose` closes unless it returns `false`.

## Validation Indicators

The step number circles in the wizard navigation bar reflect the validation state of each step:
Expand Down
Loading
Loading