Skip to content
Open
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
29 changes: 29 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,32 @@
## 6.3.0

### Nodes and layout

- `ChartNode` (`chart`): a line/area chart with bindable `points`,
`markers` and `selectedX`, grid, labels, ranges, a reference line and a
selection band.
- `ListViewProperties.wrap` and `runSpacing`: a list with a known item
count flows its items onto runs; the gap between items is the separator
spacing.
- `InputDecorationModel.contentPadding`.

### Bindings

- `TypedValue` reads `CornerRadius` (a number, `[tl, tr, br, bl]` or its
JSON) and reads `EdgeInsetsModel` from text and one-item lists, for
`cornerRadius` and `padding` bindings.

### Actions

- `DialogPresentation.sideSheet`, and `ShowDialogAction.insets` and
`maxHeightFactor`.
- `NavigationAction.destinationId` defaults to `''`, so a pop needs none.
- `SetCloudStorageAction`: `removeDocuments` (ids, where filters or the
whole collection) and `setDocuments` (a list of documents, id field,
merge, replace the collection).
- `ShowToastAction`: `cornerRadius`, `fontSize`, `fontFamily`, `fontWeight`,
`actionColor`, `showClose` and a bindable `offset`.

## 6.2.0

### Layout
Expand Down
5 changes: 3 additions & 2 deletions lib/src/api/models/action/navigation_action.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ class NavigationAction extends ActionModel with Equatable, SerializableMixin {
/// Defines how the navigation should be performed.
final NavigationType navigationType;

/// Destination canvas node's ID.
/// Destination canvas node's ID. Empty for a pop, which has no
/// destination.
final String destinationId;

/// Parameters to pass to the destination page.
Expand All @@ -47,7 +48,7 @@ class NavigationAction extends ActionModel with Equatable, SerializableMixin {
/// Creates a new [NavigationAction].
NavigationAction({
this.navigationType = NavigationType.push,
required this.destinationId,
this.destinationId = '',
Map<String, dynamic>? params,
super.nonBlocking,
super.enabled,
Expand Down
3 changes: 2 additions & 1 deletion lib/src/api/models/action/navigation_action.g.dart

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

151 changes: 149 additions & 2 deletions lib/src/api/models/action/set_cloud_storage_action.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,23 @@ enum SetCloudStorageOperation {
updateDocument,

/// Removes an existing document from the collection.
removeDocument;
removeDocument,

/// Removes many documents of a collection in one write: all of them, those
/// matching where filters, or those with the given ids.
removeDocuments,

/// Writes a list of documents to a collection in one write, e.g. restoring
/// seed data from a list variable.
setDocuments;

/// Displayable string representation of the [StorageOperation].
String get label => switch (this) {
SetCloudStorageOperation.addDocument => 'Add Document',
SetCloudStorageOperation.updateDocument => 'Update Document',
SetCloudStorageOperation.removeDocument => 'Remove Document',
SetCloudStorageOperation.removeDocuments => 'Remove Documents',
SetCloudStorageOperation.setDocuments => 'Set Documents',
};

/// Whether this [StorageOperation] is [addDocument].
Expand All @@ -32,14 +42,24 @@ enum SetCloudStorageOperation {

/// Whether this [StorageOperation] is [removeDocument].
bool get isRemoveDocument => this == removeDocument;

/// Whether this [StorageOperation] is [removeDocuments].
bool get isRemoveDocuments => this == removeDocuments;

/// Whether this [StorageOperation] is [setDocuments].
bool get isSetDocuments => this == setDocuments;

/// Whether this operation writes many documents at once.
bool get isBatch => this == removeDocuments || this == setDocuments;
}

/// An action that changes data in cloud storage.
@JsonSerializable()
class SetCloudStorageAction extends ActionModel
with Equatable, SerializableMixin {
/// The sub action to perform. This can be one of [AddDocumentSubAction],
/// [UpdateDocumentSubAction] or [RemoveDocumentSubAction].
/// [UpdateDocumentSubAction], [RemoveDocumentSubAction],
/// [RemoveDocumentsSubAction] or [SetDocumentsSubAction].
final SetCloudStorageSubAction subAction;

/// Creates a new [SetCloudStorageAction].
Expand Down Expand Up @@ -91,6 +111,11 @@ sealed class SetCloudStorageSubAction with Equatable, SerializableMixin {
UpdateDocumentSubAction.fromJson(json),
SetCloudStorageOperation.removeDocument =>
RemoveDocumentSubAction.fromJson(json),
SetCloudStorageOperation.removeDocuments =>
RemoveDocumentsSubAction.fromJson(json),
SetCloudStorageOperation.setDocuments => SetDocumentsSubAction.fromJson(
json,
),
};
}
}
Expand Down Expand Up @@ -380,3 +405,125 @@ class UpdateDocumentSubAction extends SetCloudStorageSubAction
numberOperation,
];
}

/// Represents a sub action that removes many documents of a collection in
/// cloud storage in one write (Firestore batches of up to 500 deletes).
///
/// Removes the documents whose ids [documentIds] gives, or, when it is
/// empty, the documents matching [whereFilters]: every document of the
/// collection when there are none. In a collection only the owner can read,
/// only the signed-in user's documents are removed.
@JsonSerializable()
class RemoveDocumentsSubAction extends SetCloudStorageSubAction {
/// Path to the collection, as in [RemoveDocumentSubAction.path].
final String path;

/// The ids of the documents to remove: a `${...}` path or formula giving a
/// list of ids (or of documents, whose `id` is used), a JSON list, or ids
/// separated by commas. Empty to remove by [whereFilters] instead.
final String documentIds;

/// The filters documents must pass to be removed when [documentIds] is
/// empty. No filters removes every document of the collection.
@JsonKey(defaultValue: [])
final List<WhereQueryFilter> whereFilters;

/// Creates a new [RemoveDocumentsSubAction].
const RemoveDocumentsSubAction({
this.path = '',
this.documentIds = '',
this.whereFilters = const [],
}) : super(operation: SetCloudStorageOperation.removeDocuments);

/// Duplicates this [RemoveDocumentsSubAction] with given data overrides.
RemoveDocumentsSubAction copyWith({
String? path,
String? documentIds,
List<WhereQueryFilter>? whereFilters,
}) => RemoveDocumentsSubAction(
path: path ?? this.path,
documentIds: documentIds ?? this.documentIds,
whereFilters: whereFilters ?? this.whereFilters,
);

/// Creates a new [RemoveDocumentsSubAction] instance from a JSON data.
factory RemoveDocumentsSubAction.fromJson(Map json) =>
_$RemoveDocumentsSubActionFromJson(json);

@override
Map toJson() => _$RemoveDocumentsSubActionOmitDefaults(
this,
_$RemoveDocumentsSubActionToJson(this),
)..['operation'] = operation.name;

@override
List<Object?> get props => [path, documentIds, whereFilters];
}

/// Represents a sub action that writes a list of documents to a collection
/// in cloud storage in one write (Firestore batches of up to 500 writes).
@JsonSerializable()
class SetDocumentsSubAction extends SetCloudStorageSubAction {
/// Path to the collection, as in [AddDocumentSubAction.path].
final String path;

/// The documents to write: a `${...}` path or formula giving a list of
/// maps, or a JSON list of objects (which may hold `${...}` paths).
final String documents;

/// The field of each document that holds its id. A document without one
/// gets a generated id.
final String idField;

/// Whether to merge each document into the stored one instead of
/// replacing it.
final bool merge;

/// Whether to also remove the collection's documents that are not in the
/// list, so the collection holds exactly [documents] (restoring seed
/// data).
final bool replaceCollection;

/// Creates a new [SetDocumentsSubAction].
const SetDocumentsSubAction({
this.path = '',
this.documents = '',
this.idField = 'id',
this.merge = false,
this.replaceCollection = false,
}) : super(operation: SetCloudStorageOperation.setDocuments);

/// Duplicates this [SetDocumentsSubAction] with given data overrides.
SetDocumentsSubAction copyWith({
String? path,
String? documents,
String? idField,
bool? merge,
bool? replaceCollection,
}) => SetDocumentsSubAction(
path: path ?? this.path,
documents: documents ?? this.documents,
idField: idField ?? this.idField,
merge: merge ?? this.merge,
replaceCollection: replaceCollection ?? this.replaceCollection,
);

/// Creates a new [SetDocumentsSubAction] instance from a JSON data.
factory SetDocumentsSubAction.fromJson(Map json) =>
_$SetDocumentsSubActionFromJson(json);

@override
Map toJson() => _$SetDocumentsSubActionOmitDefaults(
this,
_$SetDocumentsSubActionToJson(this),
)..['operation'] = operation.name;

@override
List<Object?> get props => [
path,
documents,
idField,
merge,
replaceCollection,
];
}
65 changes: 65 additions & 0 deletions lib/src/api/models/action/set_cloud_storage_action.g.dart

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

Loading
Loading