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
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,25 @@
## 5.2.0

### New actions

- `AuthAction` (`ActionType.auth`): sign up, sign in, sign out, update the
profile and send a password reset email (`AuthOperation`), with an
optional error variable.
- `ConditionalAction` (`ActionType.conditional`): an expression with
then/else action lists, so action chains can branch.
- `ForEachAction` (`ActionType.forEach`): runs actions for each item of a
list variable.
- `CloudFilesAction` (`ActionType.cloudFiles`): picks and uploads images to
the project's storage, or deletes a file, running nested actions per file.

### Changes

- `RowColumnNode` has a corner radius.
- 8-digit `#AARRGGBB` colors set the paint's opacity when none is given.
- Dates in list and map variables encode as ISO 8601 strings
(`encodeJsonValue`), and `VariableType.fromObjectType` maps `DateTime` to
text.

## 5.1.0

### New nodes
Expand Down
30 changes: 29 additions & 1 deletion lib/src/api/models/action/action.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,19 @@ enum ActionType {
setCloudStorage,

/// Load data from cloud storage.
loadFromCloudStorage;
loadFromCloudStorage,

/// Sign app users in and out.
auth,

/// Branch on an expression.
conditional,

/// Run actions for each item of a list.
forEach,

/// Upload or delete files in cloud storage.
cloudFiles;

/// Displayable string representation of the [ActionType].
String get prettify {
Expand Down Expand Up @@ -66,6 +78,14 @@ enum ActionType {
return 'Set Cloud Storage';
case ActionType.loadFromCloudStorage:
return 'Load from Cloud Storage';
case ActionType.auth:
return 'Authentication';
case ActionType.conditional:
return 'If / Else';
case ActionType.forEach:
return 'For Each';
case ActionType.cloudFiles:
return 'Cloud Files';
}
}
}
Expand Down Expand Up @@ -139,6 +159,14 @@ abstract class ActionModel with SerializableMixin {
return SetCloudStorageAction.fromJson(json);
case ActionType.loadFromCloudStorage:
return LoadFromCloudStorageAction.fromJson(json);
case ActionType.auth:
return AuthAction.fromJson(json);
case ActionType.conditional:
return ConditionalAction.fromJson(json);
case ActionType.forEach:
return ForEachAction.fromJson(json);
case ActionType.cloudFiles:
return CloudFilesAction.fromJson(json);
}
}

Expand Down
4 changes: 4 additions & 0 deletions lib/src/api/models/action/api_call_action.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

112 changes: 112 additions & 0 deletions lib/src/api/models/action/auth_action.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import 'package:equatable/equatable.dart';
import 'package:json_annotation/json_annotation.dart';

import '../../mixins.dart';
import '../models.dart';

part 'auth_action.g.dart';

/// What an [AuthAction] does to the app's signed-in user.
enum AuthOperation {
/// Signs in with [AuthAction.email] and [AuthAction.password].
signIn,

/// Creates an account with [AuthAction.email] and [AuthAction.password],
/// and sets its display name to [AuthAction.displayName] when given.
signUp,

/// Signs the user out.
signOut,

/// Sets the signed-in user's display name to [AuthAction.displayName].
updateProfile,

/// Sends a password reset email to [AuthAction.email].
sendPasswordResetEmail;

/// A readable name for this operation.
String get label => switch (this) {
signIn => 'Sign In',
signUp => 'Sign Up',
signOut => 'Sign Out',
updateProfile => 'Update Profile',
sendPasswordResetEmail => 'Send Password Reset Email',
};
}

/// Signs app users in and out with email and password.
///
/// The signed-in user is available to layouts as the `auth` variable:
/// `${auth.uid}`, `${auth.email}`, `${auth.displayName}` and
/// `${auth.isSignedIn}`.
///
/// [email], [password] and [displayName] may contain variable paths, e.g.
/// `${email}`. When the operation fails, the action fails, which stops the
/// actions after it, and a readable message is written to [errorVariable]
/// when one is set. On success [errorVariable] is cleared.
@JsonSerializable()
class AuthAction extends ActionModel with Equatable, SerializableMixin {
/// What to do.
final AuthOperation operation;

/// The email address, for [AuthOperation.signIn], [AuthOperation.signUp]
/// and [AuthOperation.sendPasswordResetEmail].
final String email;

/// The password, for [AuthOperation.signIn] and [AuthOperation.signUp].
final String password;

/// The display name, for [AuthOperation.signUp] and
/// [AuthOperation.updateProfile].
final String displayName;

/// A text variable that receives the error message when the operation
/// fails, and is cleared when it succeeds.
final VariableData? errorVariable;

/// Creates an [AuthAction].
AuthAction({
this.operation = AuthOperation.signIn,
this.email = '',
this.password = '',
this.displayName = '',
this.errorVariable,
super.nonBlocking,
super.enabled,
}) : super(type: ActionType.auth);

/// Duplicates this action with the given values replaced.
AuthAction copyWith({
AuthOperation? operation,
String? email,
String? password,
String? displayName,
VariableData? errorVariable,
}) => AuthAction(
operation: operation ?? this.operation,
email: email ?? this.email,
password: password ?? this.password,
displayName: displayName ?? this.displayName,
errorVariable: errorVariable ?? this.errorVariable,
nonBlocking: nonBlocking,
enabled: enabled,
);

@override
List<Object?> get props => [
operation,
email,
password,
displayName,
errorVariable,
];

/// Creates an instance from a JSON object.
factory AuthAction.fromJson(Map json) => _$AuthActionFromJson(json);

@override
Map toJson() => _$AuthActionOmitDefaults(this, _$AuthActionToJson(this));

@override
R? accept<R>(ActionVisitor<R> visitor) => visitor.visitAuthAction(this);
}
80 changes: 80 additions & 0 deletions lib/src/api/models/action/auth_action.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions lib/src/api/models/action/call_function_action.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading