Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
87e7c18185 | ||
|
|
fba6106787 | ||
|
|
d7fae6fa73 | ||
|
|
805cbcb518 |
No files matched your search
+111
@@ -0,0 +1,111 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:appflowy/plugins/database/application/cell/cell_controller_builder.dart';
|
||||
import 'package:appflowy/plugins/database/application/field/field_info.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'tag_cell_bloc.freezed.dart';
|
||||
|
||||
class TagCellBloc extends Bloc<TagCellEvent, TagCellState> {
|
||||
TagCellBloc({
|
||||
required this.cellController,
|
||||
}) : super(TagCellState.initial(cellController)) {
|
||||
_dispatch();
|
||||
_startListening();
|
||||
}
|
||||
|
||||
final TagCellController cellController;
|
||||
void Function()? _onCellChangedFn;
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
if (_onCellChangedFn != null) {
|
||||
cellController.removeListener(
|
||||
onCellChanged: _onCellChangedFn!,
|
||||
onFieldChanged: _onFieldChangedListener,
|
||||
);
|
||||
}
|
||||
await cellController.dispose();
|
||||
return super.close();
|
||||
}
|
||||
|
||||
void _dispatch() {
|
||||
on<TagCellEvent>(
|
||||
(event, emit) async {
|
||||
await event.when(
|
||||
didReceiveCellUpdate: (cellData) {
|
||||
emit(
|
||||
state.copyWith(content: cellData ?? ""),
|
||||
);
|
||||
},
|
||||
didUpdateField: (fieldInfo) {
|
||||
final wrap = fieldInfo.wrapCellContent;
|
||||
if (wrap != null) {
|
||||
emit(state.copyWith(wrap: wrap));
|
||||
}
|
||||
},
|
||||
updateCell: (text) async {
|
||||
if (state.content != text) {
|
||||
emit(state.copyWith(content: text));
|
||||
await cellController.saveCellData(text);
|
||||
|
||||
// If the input content is "abc" that can't parsered as number then the data stored in the backend will be an empty string.
|
||||
// So for every cell data that will be formatted in the backend.
|
||||
// It needs to get the formatted data after saving.
|
||||
add(
|
||||
TagCellEvent.didReceiveCellUpdate(
|
||||
cellController.getCellData() ?? "",
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void _startListening() {
|
||||
_onCellChangedFn = cellController.addListener(
|
||||
onCellChanged: (cellContent) {
|
||||
if (!isClosed) {
|
||||
add(
|
||||
TagCellEvent.didReceiveCellUpdate(cellContent ?? ""),
|
||||
);
|
||||
}
|
||||
},
|
||||
onFieldChanged: _onFieldChangedListener,
|
||||
);
|
||||
}
|
||||
|
||||
void _onFieldChangedListener(FieldInfo fieldInfo) {
|
||||
if (!isClosed) {
|
||||
add(TagCellEvent.didUpdateField(fieldInfo));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@freezed
|
||||
class TagCellEvent with _$TagCellEvent {
|
||||
const factory TagCellEvent.didReceiveCellUpdate(String? cellContent) =
|
||||
_DidReceiveCellUpdate;
|
||||
const factory TagCellEvent.didUpdateField(FieldInfo fieldInfo) =
|
||||
_DidUpdateField;
|
||||
const factory TagCellEvent.updateCell(String text) = _UpdateCell;
|
||||
}
|
||||
|
||||
@freezed
|
||||
class TagCellState with _$TagCellState {
|
||||
const factory TagCellState({
|
||||
required String content,
|
||||
required bool wrap,
|
||||
}) = _TagCellState;
|
||||
|
||||
factory TagCellState.initial(TagCellController cellController) {
|
||||
final wrap = cellController.fieldInfo.wrapCellContent;
|
||||
return TagCellState(
|
||||
content: cellController.getCellData() ?? "",
|
||||
wrap: wrap ?? true,
|
||||
);
|
||||
}
|
||||
}
|
||||
+1
@@ -18,6 +18,7 @@ typedef RelationCellController = CellController<RelationCellDataPB, String>;
|
||||
typedef SummaryCellController = CellController<String, String>;
|
||||
typedef TimeCellController = CellController<TimeCellDataPB, String>;
|
||||
typedef TranslateCellController = CellController<String, String>;
|
||||
typedef TagCellController = CellController<String, String>;
|
||||
|
||||
CellController makeCellController(
|
||||
DatabaseController databaseController,
|
||||
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
import 'package:appflowy/plugins/database/application/cell/bloc/tag_cell.bloc.dart';
|
||||
import 'package:appflowy/plugins/database/application/cell/cell_controller.dart';
|
||||
import 'package:appflowy/plugins/database/application/cell/cell_controller_builder.dart';
|
||||
import 'package:appflowy/plugins/database/application/database_controller.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import 'card_cell.dart';
|
||||
|
||||
class TagCardCellStyle extends CardCellStyle {
|
||||
const TagCardCellStyle({
|
||||
required super.padding,
|
||||
required this.textStyle,
|
||||
});
|
||||
|
||||
final TextStyle textStyle;
|
||||
}
|
||||
|
||||
class TagCardCell extends CardCell<TagCardCellStyle> {
|
||||
const TagCardCell({
|
||||
super.key,
|
||||
required super.style,
|
||||
required this.databaseController,
|
||||
required this.cellContext,
|
||||
});
|
||||
|
||||
final DatabaseController databaseController;
|
||||
final CellContext cellContext;
|
||||
|
||||
@override
|
||||
State<TagCardCell> createState() => _TagCellState();
|
||||
}
|
||||
|
||||
class _TagCellState extends State<TagCardCell> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) {
|
||||
return TagCellBloc(
|
||||
cellController: makeCellController(
|
||||
widget.databaseController,
|
||||
widget.cellContext,
|
||||
).as(),
|
||||
);
|
||||
},
|
||||
child: BlocBuilder<TagCellBloc, TagCellState>(
|
||||
buildWhen: (previous, current) => previous.content != current.content,
|
||||
builder: (context, state) {
|
||||
if (state.content.isEmpty) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
return Container(
|
||||
alignment: AlignmentDirectional.centerStart,
|
||||
padding: widget.style.padding,
|
||||
child: Text(state.content, style: widget.style.textStyle),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
+7
-1
@@ -1,3 +1,5 @@
|
||||
import 'package:appflowy/plugins/database/widgets/cell/card_cell_skeleton/tag_card_cell.dart';
|
||||
import 'package:appflowy/plugins/database/widgets/cell/card_cell_skeleton/translate_card_cell.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy/plugins/database/widgets/cell/card_cell_skeleton/summary_card_cell.dart';
|
||||
@@ -89,7 +91,11 @@ CardCellStyleMap mobileBoardCardCellStyleMap(BuildContext context) {
|
||||
padding: padding,
|
||||
textStyle: textStyle,
|
||||
),
|
||||
FieldType.Translate: SummaryCardCellStyle(
|
||||
FieldType.Translate: TranslateCardCellStyle(
|
||||
padding: padding,
|
||||
textStyle: textStyle,
|
||||
),
|
||||
FieldType.Tag: TagCardCellStyle(
|
||||
padding: padding,
|
||||
textStyle: textStyle,
|
||||
),
|
||||
|
||||
@@ -24,6 +24,7 @@ const List<FieldType> _supportedFieldTypes = [
|
||||
FieldType.Summary,
|
||||
FieldType.Time,
|
||||
FieldType.Translate,
|
||||
FieldType.Tag,
|
||||
];
|
||||
|
||||
class FieldTypeList extends StatelessWidget with FlowyOverlayDelegate {
|
||||
|
||||
+2
-1
@@ -1,7 +1,6 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy/plugins/database/widgets/field/type_option_editor/translate.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
|
||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||
@@ -18,6 +17,7 @@ import 'summary.dart';
|
||||
import 'time.dart';
|
||||
import 'timestamp.dart';
|
||||
import 'url.dart';
|
||||
import 'tag.dart';
|
||||
|
||||
typedef TypeOptionDataCallback = void Function(Uint8List typeOptionData);
|
||||
|
||||
@@ -38,6 +38,7 @@ abstract class TypeOptionEditorFactory {
|
||||
FieldType.Summary => const SummaryTypeOptionEditorFactory(),
|
||||
FieldType.Time => const TimeTypeOptionEditorFactory(),
|
||||
FieldType.Translate => const TranslateTypeOptionEditorFactory(),
|
||||
FieldType.Tag => const TagTypeOptionEditorFactory(),
|
||||
_ => throw UnimplementedError(),
|
||||
};
|
||||
}
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
|
||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'builder.dart';
|
||||
|
||||
class TagTypeOptionEditorFactory implements TypeOptionEditorFactory {
|
||||
const TagTypeOptionEditorFactory();
|
||||
|
||||
@override
|
||||
Widget? build({
|
||||
required BuildContext context,
|
||||
required String viewId,
|
||||
required FieldPB field,
|
||||
required PopoverMutex popoverMutex,
|
||||
required TypeOptionDataCallback onTypeOptionUpdated,
|
||||
}) =>
|
||||
null;
|
||||
}
|
||||
@@ -24,6 +24,7 @@ extension FieldTypeExtension on FieldType {
|
||||
FieldType.Summary => LocaleKeys.grid_field_summaryFieldName.tr(),
|
||||
FieldType.Time => LocaleKeys.grid_field_timeFieldName.tr(),
|
||||
FieldType.Translate => LocaleKeys.grid_field_translateFieldName.tr(),
|
||||
FieldType.Tag => LocaleKeys.grid_field_tagFieldName.tr(),
|
||||
_ => throw UnimplementedError(),
|
||||
};
|
||||
|
||||
@@ -42,12 +43,14 @@ extension FieldTypeExtension on FieldType {
|
||||
FieldType.Summary => FlowySvgs.ai_summary_s,
|
||||
FieldType.Time => FlowySvgs.timer_start_s,
|
||||
FieldType.Translate => FlowySvgs.ai_translate_s,
|
||||
FieldType.Tag => FlowySvgs.ai_tag_s,
|
||||
_ => throw UnimplementedError(),
|
||||
};
|
||||
|
||||
FlowySvgData? get rightIcon => switch (this) {
|
||||
FieldType.Summary => FlowySvgs.ai_indicator_s,
|
||||
FieldType.Translate => FlowySvgs.ai_indicator_s,
|
||||
FieldType.Tag => FlowySvgs.ai_indicator_s,
|
||||
_ => null,
|
||||
};
|
||||
|
||||
@@ -66,6 +69,7 @@ extension FieldTypeExtension on FieldType {
|
||||
FieldType.Summary => const Color(0xFFBECCFF),
|
||||
FieldType.Time => const Color(0xFFFDEDA7),
|
||||
FieldType.Translate => const Color(0xFFBECCFF),
|
||||
FieldType.Tag => const Color(0xFFBECCFF),
|
||||
_ => throw UnimplementedError(),
|
||||
};
|
||||
|
||||
@@ -85,6 +89,7 @@ extension FieldTypeExtension on FieldType {
|
||||
FieldType.Summary => const Color(0xFF6859A7),
|
||||
FieldType.Time => const Color(0xFFFDEDA7),
|
||||
FieldType.Translate => const Color(0xFF6859A7),
|
||||
FieldType.Tag => const Color(0xFF6859A7),
|
||||
_ => throw UnimplementedError(),
|
||||
};
|
||||
}
|
||||
+14
-29
@@ -172,7 +172,7 @@ checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
|
||||
[[package]]
|
||||
name = "app-error"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ff4384fbd07a4b7394a9af8c9159cd65715d3471#ff4384fbd07a4b7394a9af8c9159cd65715d3471"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
@@ -192,7 +192,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "appflowy-ai-client"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ff4384fbd07a4b7394a9af8c9159cd65715d3471#ff4384fbd07a4b7394a9af8c9159cd65715d3471"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@@ -203,20 +203,6 @@ dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "appflowy-cloud-billing-client"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud-Billing-Client?rev=9f9c2d1ad180987a31d18c6c067a56a5fa1f6da6#9f9c2d1ad180987a31d18c6c067a56a5fa1f6da6"
|
||||
dependencies = [
|
||||
"client-api",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"shared-entity",
|
||||
"tokio",
|
||||
"yrs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "appflowy_tauri"
|
||||
version = "0.0.0"
|
||||
@@ -786,7 +772,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "client-api"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ff4384fbd07a4b7394a9af8c9159cd65715d3471#ff4384fbd07a4b7394a9af8c9159cd65715d3471"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"again",
|
||||
"anyhow",
|
||||
@@ -833,7 +819,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "client-websocket"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ff4384fbd07a4b7394a9af8c9159cd65715d3471#ff4384fbd07a4b7394a9af8c9159cd65715d3471"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-util",
|
||||
@@ -1073,7 +1059,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-rt-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ff4384fbd07a4b7394a9af8c9159cd65715d3471#ff4384fbd07a4b7394a9af8c9159cd65715d3471"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
@@ -1098,7 +1084,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-rt-protocol"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ff4384fbd07a4b7394a9af8c9159cd65715d3471#ff4384fbd07a4b7394a9af8c9159cd65715d3471"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -1344,7 +1330,7 @@ dependencies = [
|
||||
"cssparser-macros",
|
||||
"dtoa-short",
|
||||
"itoa 1.0.6",
|
||||
"phf 0.11.2",
|
||||
"phf 0.8.0",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
@@ -1455,7 +1441,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308"
|
||||
[[package]]
|
||||
name = "database-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ff4384fbd07a4b7394a9af8c9159cd65715d3471#ff4384fbd07a4b7394a9af8c9159cd65715d3471"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
@@ -2262,7 +2248,6 @@ name = "flowy-server"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"appflowy-cloud-billing-client",
|
||||
"bytes",
|
||||
"chrono",
|
||||
"client-api",
|
||||
@@ -2876,7 +2861,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gotrue"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ff4384fbd07a4b7394a9af8c9159cd65715d3471#ff4384fbd07a4b7394a9af8c9159cd65715d3471"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"futures-util",
|
||||
@@ -2893,7 +2878,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gotrue-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ff4384fbd07a4b7394a9af8c9159cd65715d3471#ff4384fbd07a4b7394a9af8c9159cd65715d3471"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
@@ -3325,7 +3310,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "infra"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ff4384fbd07a4b7394a9af8c9159cd65715d3471#ff4384fbd07a4b7394a9af8c9159cd65715d3471"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"reqwest",
|
||||
@@ -4830,7 +4815,7 @@ checksum = "c55e02e35260070b6f716a2423c2ff1c3bb1642ddca6f99e1f26d06268a0e2d2"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"heck 0.4.1",
|
||||
"itertools 0.11.0",
|
||||
"itertools 0.10.5",
|
||||
"log",
|
||||
"multimap",
|
||||
"once_cell",
|
||||
@@ -4851,7 +4836,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools 0.11.0",
|
||||
"itertools 0.10.5",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.47",
|
||||
@@ -5815,7 +5800,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "shared-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ff4384fbd07a4b7394a9af8c9159cd65715d3471#ff4384fbd07a4b7394a9af8c9159cd65715d3471"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
|
||||
@@ -52,7 +52,7 @@ collab-user = { version = "0.2" }
|
||||
# Run the script:
|
||||
# scripts/tool/update_client_api_rev.sh new_rev_id
|
||||
# ⚠️⚠️⚠️️
|
||||
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "9d3d28ad8937712cc688c20be7c0ee6e4d14a168" }
|
||||
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "44ffc45c50e7fe362bd3f5ab4c7452e045d6b358" }
|
||||
|
||||
[dependencies]
|
||||
serde_json.workspace = true
|
||||
|
||||
+13
-42
@@ -216,7 +216,7 @@ checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
|
||||
[[package]]
|
||||
name = "app-error"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ff4384fbd07a4b7394a9af8c9159cd65715d3471#ff4384fbd07a4b7394a9af8c9159cd65715d3471"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
@@ -236,7 +236,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "appflowy-ai-client"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ff4384fbd07a4b7394a9af8c9159cd65715d3471#ff4384fbd07a4b7394a9af8c9159cd65715d3471"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@@ -247,20 +247,6 @@ dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "appflowy-cloud-billing-client"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud-Billing-Client?rev=9f9c2d1ad180987a31d18c6c067a56a5fa1f6da6#9f9c2d1ad180987a31d18c6c067a56a5fa1f6da6"
|
||||
dependencies = [
|
||||
"client-api",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"shared-entity",
|
||||
"tokio",
|
||||
"yrs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arc-swap"
|
||||
version = "1.7.1"
|
||||
@@ -576,7 +562,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "client-api"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ff4384fbd07a4b7394a9af8c9159cd65715d3471#ff4384fbd07a4b7394a9af8c9159cd65715d3471"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"again",
|
||||
"anyhow",
|
||||
@@ -623,7 +609,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "client-websocket"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ff4384fbd07a4b7394a9af8c9159cd65715d3471#ff4384fbd07a4b7394a9af8c9159cd65715d3471"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-util",
|
||||
@@ -801,7 +787,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-rt-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ff4384fbd07a4b7394a9af8c9159cd65715d3471#ff4384fbd07a4b7394a9af8c9159cd65715d3471"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
@@ -826,7 +812,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-rt-protocol"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ff4384fbd07a4b7394a9af8c9159cd65715d3471#ff4384fbd07a4b7394a9af8c9159cd65715d3471"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -995,7 +981,7 @@ dependencies = [
|
||||
"cssparser-macros",
|
||||
"dtoa-short",
|
||||
"itoa",
|
||||
"phf 0.11.2",
|
||||
"phf 0.8.0",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
@@ -1040,7 +1026,7 @@ checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5"
|
||||
[[package]]
|
||||
name = "database-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ff4384fbd07a4b7394a9af8c9159cd65715d3471#ff4384fbd07a4b7394a9af8c9159cd65715d3471"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
@@ -1546,7 +1532,6 @@ name = "flowy-server"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"appflowy-cloud-billing-client",
|
||||
"bytes",
|
||||
"chrono",
|
||||
"client-api",
|
||||
@@ -1901,7 +1886,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gotrue"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ff4384fbd07a4b7394a9af8c9159cd65715d3471#ff4384fbd07a4b7394a9af8c9159cd65715d3471"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"futures-util",
|
||||
@@ -1918,7 +1903,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gotrue-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ff4384fbd07a4b7394a9af8c9159cd65715d3471#ff4384fbd07a4b7394a9af8c9159cd65715d3471"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
@@ -2219,7 +2204,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "infra"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ff4384fbd07a4b7394a9af8c9159cd65715d3471#ff4384fbd07a4b7394a9af8c9159cd65715d3471"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"reqwest",
|
||||
@@ -2936,7 +2921,7 @@ version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12"
|
||||
dependencies = [
|
||||
"phf_macros 0.8.0",
|
||||
"phf_macros",
|
||||
"phf_shared 0.8.0",
|
||||
"proc-macro-hack",
|
||||
]
|
||||
@@ -2956,7 +2941,6 @@ version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc"
|
||||
dependencies = [
|
||||
"phf_macros 0.11.2",
|
||||
"phf_shared 0.11.2",
|
||||
]
|
||||
|
||||
@@ -3024,19 +3008,6 @@ dependencies = [
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_macros"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b"
|
||||
dependencies = [
|
||||
"phf_generator 0.11.2",
|
||||
"phf_shared 0.11.2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_shared"
|
||||
version = "0.8.0"
|
||||
@@ -3921,7 +3892,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "shared-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ff4384fbd07a4b7394a9af8c9159cd65715d3471#ff4384fbd07a4b7394a9af8c9159cd65715d3471"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
|
||||
@@ -55,7 +55,7 @@ yrs = "0.18.8"
|
||||
# Run the script:
|
||||
# scripts/tool/update_client_api_rev.sh new_rev_id
|
||||
# ⚠️⚠️⚠️️
|
||||
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "9d3d28ad8937712cc688c20be7c0ee6e4d14a168" }
|
||||
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "44ffc45c50e7fe362bd3f5ab4c7452e045d6b358" }
|
||||
|
||||
[profile.dev]
|
||||
opt-level = 0
|
||||
|
||||
+16
-15
@@ -163,7 +163,7 @@ checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247"
|
||||
[[package]]
|
||||
name = "app-error"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ff4384fbd07a4b7394a9af8c9159cd65715d3471#ff4384fbd07a4b7394a9af8c9159cd65715d3471"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
@@ -183,7 +183,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "appflowy-ai-client"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ff4384fbd07a4b7394a9af8c9159cd65715d3471#ff4384fbd07a4b7394a9af8c9159cd65715d3471"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@@ -746,7 +746,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "client-api"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ff4384fbd07a4b7394a9af8c9159cd65715d3471#ff4384fbd07a4b7394a9af8c9159cd65715d3471"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"again",
|
||||
"anyhow",
|
||||
@@ -793,7 +793,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "client-websocket"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ff4384fbd07a4b7394a9af8c9159cd65715d3471#ff4384fbd07a4b7394a9af8c9159cd65715d3471"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-util",
|
||||
@@ -1042,7 +1042,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-rt-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ff4384fbd07a4b7394a9af8c9159cd65715d3471#ff4384fbd07a4b7394a9af8c9159cd65715d3471"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
@@ -1067,7 +1067,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-rt-protocol"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ff4384fbd07a4b7394a9af8c9159cd65715d3471#ff4384fbd07a4b7394a9af8c9159cd65715d3471"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -1428,7 +1428,7 @@ checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5"
|
||||
[[package]]
|
||||
name = "database-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ff4384fbd07a4b7394a9af8c9159cd65715d3471#ff4384fbd07a4b7394a9af8c9159cd65715d3471"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
@@ -2248,6 +2248,7 @@ dependencies = [
|
||||
"flowy-codegen",
|
||||
"flowy-derive",
|
||||
"flowy-error",
|
||||
"flowy-folder",
|
||||
"flowy-notification",
|
||||
"flowy-search-pub",
|
||||
"flowy-sqlite",
|
||||
@@ -2934,7 +2935,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gotrue"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ff4384fbd07a4b7394a9af8c9159cd65715d3471#ff4384fbd07a4b7394a9af8c9159cd65715d3471"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"futures-util",
|
||||
@@ -2951,7 +2952,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gotrue-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ff4384fbd07a4b7394a9af8c9159cd65715d3471#ff4384fbd07a4b7394a9af8c9159cd65715d3471"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
@@ -3388,7 +3389,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "infra"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ff4384fbd07a4b7394a9af8c9159cd65715d3471#ff4384fbd07a4b7394a9af8c9159cd65715d3471"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"reqwest",
|
||||
@@ -5894,7 +5895,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "shared-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ff4384fbd07a4b7394a9af8c9159cd65715d3471#ff4384fbd07a4b7394a9af8c9159cd65715d3471"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
@@ -6873,9 +6874,9 @@ checksum = "c7c4ceeeca15c8384bbc3e011dbd8fccb7f068a440b752b7d9b32ceb0ca0e2e8"
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.36.0"
|
||||
version = "1.38.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931"
|
||||
checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"bytes",
|
||||
@@ -6893,9 +6894,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "2.2.0"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
|
||||
checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
||||
@@ -52,7 +52,7 @@ collab-user = { version = "0.2" }
|
||||
# Run the script:
|
||||
# scripts/tool/update_client_api_rev.sh new_rev_id
|
||||
# ⚠️⚠️⚠️️
|
||||
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "9d3d28ad8937712cc688c20be7c0ee6e4d14a168" }
|
||||
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "44ffc45c50e7fe362bd3f5ab4c7452e045d6b358" }
|
||||
|
||||
[dependencies]
|
||||
serde_json.workspace = true
|
||||
|
||||
@@ -1013,6 +1013,7 @@
|
||||
"summaryFieldName": "AI Summary",
|
||||
"timeFieldName": "Time",
|
||||
"translateFieldName": "AI Translate",
|
||||
"tagFieldName": "AI Tags",
|
||||
"translateTo": "Translate to",
|
||||
"numberFormat": "Number format",
|
||||
"dateFormat": "Date format",
|
||||
|
||||
Generated
+29
-15
@@ -163,7 +163,7 @@ checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
|
||||
[[package]]
|
||||
name = "app-error"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9d3d28ad8937712cc688c20be7c0ee6e4d14a168#9d3d28ad8937712cc688c20be7c0ee6e4d14a168"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
@@ -183,7 +183,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "appflowy-ai-client"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9d3d28ad8937712cc688c20be7c0ee6e4d14a168#9d3d28ad8937712cc688c20be7c0ee6e4d14a168"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@@ -664,7 +664,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "client-api"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9d3d28ad8937712cc688c20be7c0ee6e4d14a168#9d3d28ad8937712cc688c20be7c0ee6e4d14a168"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"again",
|
||||
"anyhow",
|
||||
@@ -711,7 +711,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "client-websocket"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9d3d28ad8937712cc688c20be7c0ee6e4d14a168#9d3d28ad8937712cc688c20be7c0ee6e4d14a168"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-util",
|
||||
@@ -920,7 +920,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-rt-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9d3d28ad8937712cc688c20be7c0ee6e4d14a168#9d3d28ad8937712cc688c20be7c0ee6e4d14a168"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
@@ -945,7 +945,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-rt-protocol"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9d3d28ad8937712cc688c20be7c0ee6e4d14a168#9d3d28ad8937712cc688c20be7c0ee6e4d14a168"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -1165,7 +1165,7 @@ dependencies = [
|
||||
"cssparser-macros",
|
||||
"dtoa-short",
|
||||
"itoa",
|
||||
"phf 0.8.0",
|
||||
"phf 0.11.2",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
@@ -1265,7 +1265,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308"
|
||||
[[package]]
|
||||
name = "database-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9d3d28ad8937712cc688c20be7c0ee6e4d14a168#9d3d28ad8937712cc688c20be7c0ee6e4d14a168"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
@@ -2531,7 +2531,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gotrue"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9d3d28ad8937712cc688c20be7c0ee6e4d14a168#9d3d28ad8937712cc688c20be7c0ee6e4d14a168"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"futures-util",
|
||||
@@ -2548,7 +2548,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gotrue-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9d3d28ad8937712cc688c20be7c0ee6e4d14a168#9d3d28ad8937712cc688c20be7c0ee6e4d14a168"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
@@ -2913,7 +2913,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "infra"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9d3d28ad8937712cc688c20be7c0ee6e4d14a168#9d3d28ad8937712cc688c20be7c0ee6e4d14a168"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"reqwest",
|
||||
@@ -3789,7 +3789,7 @@ version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12"
|
||||
dependencies = [
|
||||
"phf_macros",
|
||||
"phf_macros 0.8.0",
|
||||
"phf_shared 0.8.0",
|
||||
"proc-macro-hack",
|
||||
]
|
||||
@@ -3809,6 +3809,7 @@ version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc"
|
||||
dependencies = [
|
||||
"phf_macros 0.11.2",
|
||||
"phf_shared 0.11.2",
|
||||
]
|
||||
|
||||
@@ -3876,6 +3877,19 @@ dependencies = [
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_macros"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b"
|
||||
dependencies = [
|
||||
"phf_generator 0.11.2",
|
||||
"phf_shared 0.11.2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.47",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_shared"
|
||||
version = "0.8.0"
|
||||
@@ -4079,7 +4093,7 @@ checksum = "c55e02e35260070b6f716a2423c2ff1c3bb1642ddca6f99e1f26d06268a0e2d2"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"heck 0.4.1",
|
||||
"itertools 0.10.5",
|
||||
"itertools 0.11.0",
|
||||
"log",
|
||||
"multimap",
|
||||
"once_cell",
|
||||
@@ -4100,7 +4114,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools 0.10.5",
|
||||
"itertools 0.11.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.47",
|
||||
@@ -4997,7 +5011,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "shared-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9d3d28ad8937712cc688c20be7c0ee6e4d14a168#9d3d28ad8937712cc688c20be7c0ee6e4d14a168"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=44ffc45c50e7fe362bd3f5ab4c7452e045d6b358#44ffc45c50e7fe362bd3f5ab4c7452e045d6b358"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
|
||||
@@ -94,7 +94,7 @@ yrs = "0.18.8"
|
||||
# Run the script.add_workspace_members:
|
||||
# scripts/tool/update_client_api_rev.sh new_rev_id
|
||||
# ⚠️⚠️⚠️️
|
||||
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "9d3d28ad8937712cc688c20be7c0ee6e4d14a168" }
|
||||
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "44ffc45c50e7fe362bd3f5ab4c7452e045d6b358" }
|
||||
|
||||
[profile.dev]
|
||||
opt-level = 1
|
||||
|
||||
@@ -6,6 +6,7 @@ use collab_database::fields::Field;
|
||||
use collab_database::rows::Row;
|
||||
use flowy_database2::entities::FieldType;
|
||||
use flowy_database2::services::field::summary_type_option::summary::SummarizationTypeOption;
|
||||
use flowy_database2::services::field::tag_type_option::tag::TagTypeOption;
|
||||
use flowy_database2::services::field::translate_type_option::translate::TranslateTypeOption;
|
||||
use flowy_database2::services::field::{
|
||||
FieldBuilder, NumberFormat, NumberTypeOption, SelectOption, SelectOptionColor,
|
||||
@@ -63,6 +64,7 @@ fn create_fields() -> Vec<Field> {
|
||||
FieldType::SingleSelect => fields.push(create_single_select_field("Status")),
|
||||
FieldType::Summary => fields.push(create_summary_field("AI summary")),
|
||||
FieldType::Translate => fields.push(create_translate_field("AI Translate")),
|
||||
FieldType::Tag => fields.push(create_tag_field("AI Tag")),
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
@@ -137,3 +139,11 @@ fn create_translate_field(name: &str) -> Field {
|
||||
.name(name)
|
||||
.build()
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn create_tag_field(name: &str) -> Field {
|
||||
let type_option = TagTypeOption::default();
|
||||
FieldBuilder::new(FieldType::Tag, type_option)
|
||||
.name(name)
|
||||
.build()
|
||||
}
|
||||
@@ -5,7 +5,7 @@ use std::sync::Arc;
|
||||
|
||||
use anyhow::Error;
|
||||
use client_api::collab_sync::{SinkConfig, SyncObject, SyncPlugin};
|
||||
use client_api::entity::ai_dto::RepeatedRelatedQuestion;
|
||||
use client_api::entity::ai_dto::{RepeatedRelatedQuestion, TagRowResponse};
|
||||
use client_api::entity::ChatMessageType;
|
||||
use collab::core::origin::{CollabClient, CollabOrigin};
|
||||
|
||||
@@ -23,7 +23,7 @@ use flowy_chat_pub::cloud::{
|
||||
StreamAnswer,
|
||||
};
|
||||
use flowy_database_pub::cloud::{
|
||||
CollabDocStateByOid, DatabaseCloudService, DatabaseSnapshot, SummaryRowContent,
|
||||
CollabDocStateByOid, DatabaseCloudService, DatabaseSnapshot, SummaryRowContent, TagRowContent,
|
||||
TranslateRowContent, TranslateRowResponse,
|
||||
};
|
||||
use flowy_document::deps::DocumentData;
|
||||
@@ -313,6 +313,21 @@ impl DatabaseCloudService for ServerProvider {
|
||||
.await
|
||||
})
|
||||
}
|
||||
|
||||
fn tag_database_row(
|
||||
&self,
|
||||
workspace_id: &str,
|
||||
tag_row: TagRowContent,
|
||||
) -> FutureResult<TagRowResponse, Error> {
|
||||
let workspace_id = workspace_id.to_string();
|
||||
let server = self.get_server();
|
||||
FutureResult::new(async move {
|
||||
server?
|
||||
.database_service()
|
||||
.tag_database_row(&workspace_id, tag_row)
|
||||
.await
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl DocumentCloudService for ServerProvider {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
use anyhow::Error;
|
||||
pub use client_api::entity::ai_dto::{TranslateItem, TranslateRowResponse};
|
||||
pub use client_api::entity::ai_dto::{
|
||||
TagItem, TagRowData, TagRowResponse, TranslateItem, TranslateRowResponse,
|
||||
};
|
||||
use collab::core::collab::DataSource;
|
||||
use collab_entity::CollabType;
|
||||
use lib_infra::future::FutureResult;
|
||||
@@ -8,6 +10,8 @@ use std::collections::HashMap;
|
||||
pub type CollabDocStateByOid = HashMap<String, DataSource>;
|
||||
pub type SummaryRowContent = HashMap<String, String>;
|
||||
pub type TranslateRowContent = Vec<TranslateItem>;
|
||||
|
||||
pub type TagRowContent = TagRowData;
|
||||
/// A trait for database cloud service.
|
||||
/// Each kind of server should implement this trait. Check out the [AppFlowyServerProvider] of
|
||||
/// [flowy-server] crate for more information.
|
||||
@@ -48,6 +52,12 @@ pub trait DatabaseCloudService: Send + Sync {
|
||||
translate_row: TranslateRowContent,
|
||||
language: &str,
|
||||
) -> FutureResult<TranslateRowResponse, Error>;
|
||||
|
||||
fn tag_database_row(
|
||||
&self,
|
||||
workspace_id: &str,
|
||||
tag_row: TagRowContent,
|
||||
) -> FutureResult<TagRowResponse, Error>;
|
||||
}
|
||||
|
||||
pub struct DatabaseSnapshot {
|
||||
|
||||
@@ -451,6 +451,7 @@ pub enum FieldType {
|
||||
Summary = 11,
|
||||
Translate = 12,
|
||||
Time = 13,
|
||||
Tag = 14,
|
||||
}
|
||||
|
||||
impl Display for FieldType {
|
||||
@@ -492,13 +493,17 @@ impl FieldType {
|
||||
FieldType::Relation => "Relation",
|
||||
FieldType::Summary => "Summarize",
|
||||
FieldType::Translate => "Translate",
|
||||
FieldType::Tag => "Tag",
|
||||
FieldType::Time => "Time",
|
||||
};
|
||||
s.to_string()
|
||||
}
|
||||
|
||||
pub fn is_ai_field(&self) -> bool {
|
||||
matches!(self, FieldType::Summary | FieldType::Translate)
|
||||
matches!(
|
||||
self,
|
||||
FieldType::Summary | FieldType::Translate | FieldType::Tag
|
||||
)
|
||||
}
|
||||
|
||||
pub fn is_number(&self) -> bool {
|
||||
|
||||
@@ -117,6 +117,10 @@ impl From<&Filter> for FilterPB {
|
||||
.cloned::<TextFilterPB>()
|
||||
.unwrap()
|
||||
.try_into(),
|
||||
FieldType::Tag => condition_and_content
|
||||
.cloned::<TextFilterPB>()
|
||||
.unwrap()
|
||||
.try_into(),
|
||||
};
|
||||
|
||||
Self {
|
||||
@@ -170,6 +174,9 @@ impl TryFrom<FilterDataPB> for FilterInner {
|
||||
FieldType::Translate => {
|
||||
BoxAny::new(TextFilterPB::try_from(bytes).map_err(|_| ErrorCode::ProtobufSerde)?)
|
||||
},
|
||||
FieldType::Tag => {
|
||||
BoxAny::new(TextFilterPB::try_from(bytes).map_err(|_| ErrorCode::ProtobufSerde)?)
|
||||
},
|
||||
};
|
||||
|
||||
Ok(Self::Data {
|
||||
|
||||
@@ -18,6 +18,7 @@ macro_rules! impl_into_field_type {
|
||||
11 => FieldType::Summary,
|
||||
12 => FieldType::Translate,
|
||||
13 => FieldType::Time,
|
||||
14 => FieldType::Tag,
|
||||
_ => {
|
||||
tracing::error!("🔴Can't parse FieldType from value: {}", ty);
|
||||
FieldType::RichText
|
||||
|
||||
@@ -5,6 +5,7 @@ mod number_entities;
|
||||
mod relation_entities;
|
||||
mod select_option_entities;
|
||||
mod summary_entities;
|
||||
mod tag_entities;
|
||||
mod text_entities;
|
||||
mod time_entities;
|
||||
mod timestamp_entities;
|
||||
@@ -18,6 +19,7 @@ pub use number_entities::*;
|
||||
pub use relation_entities::*;
|
||||
pub use select_option_entities::*;
|
||||
pub use summary_entities::*;
|
||||
pub use tag_entities::*;
|
||||
pub use text_entities::*;
|
||||
pub use time_entities::*;
|
||||
pub use timestamp_entities::*;
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
use crate::entities::TranslateTypeOptionPB;
|
||||
use crate::services::field::tag_type_option::tag::{TagOption, TagTypeOption};
|
||||
use flowy_derive::ProtoBuf;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, Default, ProtoBuf)]
|
||||
pub struct TagTypeOptionPB {
|
||||
#[pb(index = 1)]
|
||||
pub tags: Vec<TagItemPB>,
|
||||
}
|
||||
|
||||
#[derive(ProtoBuf, Debug, Clone, Default)]
|
||||
pub struct TagItemPB {
|
||||
#[pb(index = 1)]
|
||||
color: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
text: String,
|
||||
}
|
||||
|
||||
impl From<TagOption> for TagItemPB {
|
||||
fn from(value: TagOption) -> Self {
|
||||
Self {
|
||||
color: value.color,
|
||||
text: value.text,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TagItemPB> for TagOption {
|
||||
fn from(value: TagItemPB) -> Self {
|
||||
Self {
|
||||
color: value.color,
|
||||
text: value.text,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TagTypeOption> for TagTypeOptionPB {
|
||||
fn from(value: TagTypeOption) -> Self {
|
||||
Self {
|
||||
tags: value.tags.into_iter().map(TagItemPB::from).collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TagTypeOptionPB> for TagTypeOption {
|
||||
fn from(value: TagTypeOptionPB) -> Self {
|
||||
Self {
|
||||
tags: value.tags.into_iter().map(TagOption::from).collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,8 @@ use tracing::{event, instrument, trace};
|
||||
use collab_integrate::collab_builder::{AppFlowyCollabBuilder, CollabBuilderConfig};
|
||||
use collab_integrate::{CollabKVAction, CollabKVDB, CollabPersistenceConfig};
|
||||
use flowy_database_pub::cloud::{
|
||||
DatabaseCloudService, SummaryRowContent, TranslateItem, TranslateRowContent,
|
||||
DatabaseCloudService, SummaryRowContent, TagItem, TagRowContent, TranslateItem,
|
||||
TranslateRowContent,
|
||||
};
|
||||
use flowy_error::{internal_error, FlowyError, FlowyResult};
|
||||
use lib_infra::box_any::BoxAny;
|
||||
@@ -28,6 +29,7 @@ use crate::entities::{DatabaseLayoutPB, DatabaseSnapshotPB, FieldType};
|
||||
use crate::services::cell::stringify_cell;
|
||||
use crate::services::database::DatabaseEditor;
|
||||
use crate::services::database_view::DatabaseLayoutDepsResolver;
|
||||
use crate::services::field::tag_type_option::tag::{TagOption, TagTypeOption};
|
||||
use crate::services::field::translate_type_option::translate::TranslateTypeOption;
|
||||
|
||||
use crate::services::field_settings::default_field_settings_by_layout_map;
|
||||
@@ -506,7 +508,6 @@ impl DatabaseManager {
|
||||
}
|
||||
}
|
||||
|
||||
// Call the cloud service to summarize the row.
|
||||
trace!(
|
||||
"[AI]:translate to {}, content:{:?}",
|
||||
language,
|
||||
@@ -539,6 +540,59 @@ impl DatabaseManager {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip_all)]
|
||||
pub async fn tag_row(&self, view_id: String, row_id: RowId, field_id: String) -> FlowyResult<()> {
|
||||
let database = self.get_database_with_view_id(&view_id).await?;
|
||||
let mut tag_row = TagRowContent {
|
||||
existing_tags: vec![],
|
||||
items: vec![],
|
||||
num_tags: 5,
|
||||
};
|
||||
if let Some(row) = database.get_row(&view_id, &row_id) {
|
||||
let fields = database.get_fields(&view_id, None);
|
||||
for field in fields {
|
||||
if field.id != field_id {
|
||||
if FieldType::from(field.field_type).is_ai_field() {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some(cell) = row.cells.get(&field.id) {
|
||||
tag_row.items.push(TagItem {
|
||||
title: field.name.clone(),
|
||||
content: stringify_cell(cell, &field),
|
||||
})
|
||||
}
|
||||
} else {
|
||||
tag_row.existing_tags.extend(
|
||||
field
|
||||
.type_options
|
||||
.get(&FieldType::Tag.to_string())
|
||||
.cloned()
|
||||
.map(TagTypeOption::from)
|
||||
.unwrap_or_default()
|
||||
.tags
|
||||
.into_iter()
|
||||
.map(|tag| tag.text)
|
||||
.collect::<Vec<String>>(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let response = self
|
||||
.cloud_service
|
||||
.tag_database_row(&self.user.workspace_id()?, tag_row)
|
||||
.await?;
|
||||
|
||||
// Format the response items into a single string
|
||||
let content = response.tags.join(", ");
|
||||
trace!("[AI]:tag row response: {}", content);
|
||||
database
|
||||
.update_cell_with_changeset(&view_id, &row_id, &field_id, BoxAny::new(content))
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Only expose this method for testing
|
||||
#[cfg(debug_assertions)]
|
||||
pub fn get_cloud_service(&self) -> &Arc<dyn DatabaseCloudService> {
|
||||
|
||||
@@ -265,6 +265,9 @@ impl<'a> CellBuilder<'a> {
|
||||
FieldType::Translate => {
|
||||
cells.insert(field_id, insert_text_cell(cell_str, field));
|
||||
},
|
||||
FieldType::Tag => {
|
||||
cells.insert(field_id, insert_text_cell(cell_str, field));
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ pub mod number_type_option;
|
||||
pub mod relation_type_option;
|
||||
pub mod selection_type_option;
|
||||
pub mod summary_type_option;
|
||||
pub mod tag_type_option;
|
||||
pub mod text_type_option;
|
||||
pub mod time_type_option;
|
||||
pub mod timestamp_type_option;
|
||||
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
pub mod tag;
|
||||
pub mod tag_entities;
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
use crate::entities::TextFilterPB;
|
||||
use crate::services::cell::{CellDataChangeset, CellDataDecoder};
|
||||
use crate::services::field::type_options::tag_type_option::tag_entities::TagCellData;
|
||||
use crate::services::field::type_options::util::ProtobufStr;
|
||||
use crate::services::field::{
|
||||
TypeOption, TypeOptionCellData, TypeOptionCellDataCompare, TypeOptionCellDataFilter,
|
||||
TypeOptionCellDataSerde, TypeOptionTransform,
|
||||
};
|
||||
use crate::services::sort::SortCondition;
|
||||
use collab::core::any_map::{AnyMap, AnyMapExtension};
|
||||
use collab_database::fields::{TypeOptionData, TypeOptionDataBuilder};
|
||||
use collab_database::rows::Cell;
|
||||
use flowy_error::FlowyResult;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::cmp::Ordering;
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct TagTypeOption {
|
||||
pub tags: Vec<TagOption>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct TagOption {
|
||||
pub color: String,
|
||||
pub text: String,
|
||||
}
|
||||
|
||||
impl From<AnyMap> for TagOption {
|
||||
fn from(value: AnyMap) -> Self {
|
||||
let color = value.get_str_value("color").unwrap_or_default();
|
||||
let text = value.get_str_value("text").unwrap_or_default();
|
||||
Self { color, text }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TagOption> for AnyMap {
|
||||
fn from(value: TagOption) -> Self {
|
||||
let mut map = AnyMap::new();
|
||||
map.insert_str_value("color", value.color);
|
||||
map.insert_str_value("text", value.text);
|
||||
map
|
||||
}
|
||||
}
|
||||
impl From<TypeOptionData> for TagTypeOption {
|
||||
fn from(value: TypeOptionData) -> Self {
|
||||
let tags = value.get_array("tags");
|
||||
Self { tags }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TagTypeOption> for TypeOptionData {
|
||||
fn from(value: TagTypeOption) -> Self {
|
||||
TypeOptionDataBuilder::new()
|
||||
.insert_maps("tags", value.tags)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeOption for TagTypeOption {
|
||||
type CellData = TagCellData;
|
||||
type CellChangeset = String;
|
||||
type CellProtobufType = ProtobufStr;
|
||||
type CellFilter = TextFilterPB;
|
||||
}
|
||||
|
||||
impl CellDataChangeset for TagTypeOption {
|
||||
fn apply_changeset(
|
||||
&self,
|
||||
changeset: String,
|
||||
_cell: Option<Cell>,
|
||||
) -> FlowyResult<(Cell, TagCellData)> {
|
||||
let cell_data = TagCellData(changeset);
|
||||
Ok((cell_data.clone().into(), cell_data))
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeOptionCellDataFilter for TagTypeOption {
|
||||
fn apply_filter(
|
||||
&self,
|
||||
filter: &<Self as TypeOption>::CellFilter,
|
||||
cell_data: &<Self as TypeOption>::CellData,
|
||||
) -> bool {
|
||||
filter.is_visible(cell_data)
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeOptionCellDataCompare for TagTypeOption {
|
||||
fn apply_cmp(
|
||||
&self,
|
||||
cell_data: &<Self as TypeOption>::CellData,
|
||||
other_cell_data: &<Self as TypeOption>::CellData,
|
||||
sort_condition: SortCondition,
|
||||
) -> Ordering {
|
||||
match (cell_data.is_cell_empty(), other_cell_data.is_cell_empty()) {
|
||||
(true, true) => Ordering::Equal,
|
||||
(true, false) => Ordering::Greater,
|
||||
(false, true) => Ordering::Less,
|
||||
(false, false) => {
|
||||
let order = cell_data.0.cmp(&other_cell_data.0);
|
||||
sort_condition.evaluate_order(order)
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CellDataDecoder for TagTypeOption {
|
||||
fn decode_cell(&self, cell: &Cell) -> FlowyResult<TagCellData> {
|
||||
Ok(TagCellData::from(cell))
|
||||
}
|
||||
|
||||
fn stringify_cell_data(&self, cell_data: TagCellData) -> String {
|
||||
cell_data.to_string()
|
||||
}
|
||||
|
||||
fn numeric_cell(&self, _cell: &Cell) -> Option<f64> {
|
||||
None
|
||||
}
|
||||
}
|
||||
impl TypeOptionTransform for TagTypeOption {}
|
||||
|
||||
impl TypeOptionCellDataSerde for TagTypeOption {
|
||||
fn protobuf_encode(
|
||||
&self,
|
||||
cell_data: <Self as TypeOption>::CellData,
|
||||
) -> <Self as TypeOption>::CellProtobufType {
|
||||
ProtobufStr::from(cell_data.0)
|
||||
}
|
||||
|
||||
fn parse_cell(&self, cell: &Cell) -> FlowyResult<<Self as TypeOption>::CellData> {
|
||||
Ok(TagCellData::from(cell))
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
use crate::entities::FieldType;
|
||||
use crate::services::field::{TypeOptionCellData, CELL_DATA};
|
||||
use collab::core::any_map::AnyMapExtension;
|
||||
use collab_database::rows::{new_cell_builder, Cell};
|
||||
|
||||
#[derive(Default, Debug, Clone)]
|
||||
pub struct TagCellData(pub String);
|
||||
impl std::ops::Deref for TagCellData {
|
||||
type Target = String;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeOptionCellData for TagCellData {
|
||||
fn is_cell_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Cell> for TagCellData {
|
||||
fn from(cell: &Cell) -> Self {
|
||||
Self(cell.get_str_value(CELL_DATA).unwrap_or_default())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TagCellData> for Cell {
|
||||
fn from(data: TagCellData) -> Self {
|
||||
new_cell_builder(FieldType::Tag)
|
||||
.insert_str_value(CELL_DATA, data.0)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for TagCellData {
|
||||
fn to_string(&self) -> String {
|
||||
self.0.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<str> for TagCellData {
|
||||
fn as_ref(&self) -> &str {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -82,7 +82,8 @@ impl CellDataDecoder for RichTextTypeOption {
|
||||
| FieldType::URL
|
||||
| FieldType::Summary
|
||||
| FieldType::Translate
|
||||
| FieldType::Time => Some(StringCellData::from(stringify_cell(cell, field))),
|
||||
| FieldType::Time
|
||||
| FieldType::Tag => Some(StringCellData::from(stringify_cell(cell, field))),
|
||||
FieldType::Checklist
|
||||
| FieldType::LastEditedTime
|
||||
| FieldType::CreatedTime
|
||||
|
||||
@@ -11,12 +11,13 @@ use flowy_error::FlowyResult;
|
||||
use crate::entities::{
|
||||
CheckboxTypeOptionPB, ChecklistTypeOptionPB, DateTypeOptionPB, FieldType,
|
||||
MultiSelectTypeOptionPB, NumberTypeOptionPB, RelationTypeOptionPB, RichTextTypeOptionPB,
|
||||
SingleSelectTypeOptionPB, SummarizationTypeOptionPB, TimeTypeOptionPB, TimestampTypeOptionPB,
|
||||
TranslateTypeOptionPB, URLTypeOptionPB,
|
||||
SingleSelectTypeOptionPB, SummarizationTypeOptionPB, TagTypeOptionPB, TimeTypeOptionPB,
|
||||
TimestampTypeOptionPB, TranslateTypeOptionPB, URLTypeOptionPB,
|
||||
};
|
||||
use crate::services::cell::CellDataDecoder;
|
||||
use crate::services::field::checklist_type_option::ChecklistTypeOption;
|
||||
use crate::services::field::summary_type_option::summary::SummarizationTypeOption;
|
||||
use crate::services::field::tag_type_option::tag::TagTypeOption;
|
||||
use crate::services::field::translate_type_option::translate::TranslateTypeOption;
|
||||
use crate::services::field::{
|
||||
CheckboxTypeOption, DateTypeOption, MultiSelectTypeOption, NumberTypeOption, RelationTypeOption,
|
||||
@@ -191,6 +192,7 @@ pub fn type_option_data_from_pb<T: Into<Bytes>>(
|
||||
FieldType::Translate => {
|
||||
TranslateTypeOptionPB::try_from(bytes).map(|pb| TranslateTypeOption::from(pb).into())
|
||||
},
|
||||
FieldType::Tag => TagTypeOptionPB::try_from(bytes).map(|pb| TagTypeOption::from(pb).into()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,6 +270,10 @@ pub fn type_option_to_pb(type_option: TypeOptionData, field_type: &FieldType) ->
|
||||
.try_into()
|
||||
.unwrap()
|
||||
},
|
||||
FieldType::Tag => {
|
||||
let tag_type_option: TagTypeOption = type_option.into();
|
||||
TagTypeOptionPB::from(tag_type_option).try_into().unwrap()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -289,6 +295,7 @@ pub fn default_type_option_data_from_type(field_type: FieldType) -> TypeOptionDa
|
||||
FieldType::Relation => RelationTypeOption::default().into(),
|
||||
FieldType::Summary => SummarizationTypeOption::default().into(),
|
||||
FieldType::Translate => TranslateTypeOption::default().into(),
|
||||
FieldType::Tag => TagTypeOption::default().into(),
|
||||
FieldType::Time => TimeTypeOption.into(),
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ use lib_infra::box_any::BoxAny;
|
||||
use crate::entities::FieldType;
|
||||
use crate::services::cell::{CellCache, CellDataChangeset, CellDataDecoder, CellProtobufBlob};
|
||||
use crate::services::field::summary_type_option::summary::SummarizationTypeOption;
|
||||
use crate::services::field::tag_type_option::tag::TagTypeOption;
|
||||
use crate::services::field::translate_type_option::translate::TranslateTypeOption;
|
||||
use crate::services::field::{
|
||||
CheckboxTypeOption, ChecklistTypeOption, DateTypeOption, MultiSelectTypeOption, NumberTypeOption,
|
||||
@@ -470,6 +471,18 @@ impl<'a> TypeOptionCellExt<'a> {
|
||||
self.cell_data_cache.clone(),
|
||||
)
|
||||
}),
|
||||
FieldType::Tag => {
|
||||
self
|
||||
.field
|
||||
.get_type_option::<TagTypeOption>(field_type)
|
||||
.map(|type_option| {
|
||||
TypeOptionCellDataHandlerImpl::new_with_boxed(
|
||||
type_option,
|
||||
field_type,
|
||||
self.cell_data_cache.clone(),
|
||||
)
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -579,6 +592,9 @@ fn get_type_option_transform_handler(
|
||||
FieldType::Translate => {
|
||||
Box::new(TranslateTypeOption::from(type_option_data)) as Box<dyn TypeOptionTransformHandler>
|
||||
},
|
||||
FieldType::Tag => {
|
||||
Box::new(TagTypeOption::from(type_option_data)) as Box<dyn TypeOptionTransformHandler>
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -284,6 +284,7 @@ impl FilterInner {
|
||||
FieldType::Summary => BoxAny::new(TextFilterPB::parse(condition as u8, content)),
|
||||
FieldType::Translate => BoxAny::new(TextFilterPB::parse(condition as u8, content)),
|
||||
FieldType::Time => BoxAny::new(TimeFilterPB::parse(condition as u8, content)),
|
||||
FieldType::Tag => BoxAny::new(TextFilterPB::parse(condition as u8, content)),
|
||||
};
|
||||
|
||||
FilterInner::Data {
|
||||
@@ -378,6 +379,10 @@ impl<'a> From<&'a Filter> for FilterMap {
|
||||
let filter = condition_and_content.cloned::<TextFilterPB>()?;
|
||||
(filter.condition as u8, filter.content)
|
||||
},
|
||||
FieldType::Tag => {
|
||||
let filter = condition_and_content.cloned::<TextFilterPB>()?;
|
||||
(filter.condition as u8, filter.content)
|
||||
},
|
||||
};
|
||||
Some((condition, content))
|
||||
};
|
||||
|
||||
@@ -141,6 +141,7 @@ pub fn make_test_board() -> DatabaseData {
|
||||
fields.push(time_field);
|
||||
},
|
||||
FieldType::Translate => {},
|
||||
FieldType::Tag => {},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ use crate::database::mock_data::{COMPLETED, FACEBOOK, GOOGLE, PAUSED, PLANNED, T
|
||||
use event_integration_test::database_event::TestRowBuilder;
|
||||
use flowy_database2::entities::FieldType;
|
||||
use flowy_database2::services::field::summary_type_option::summary::SummarizationTypeOption;
|
||||
use flowy_database2::services::field::tag_type_option::tag::TagTypeOption;
|
||||
use flowy_database2::services::field::translate_type_option::translate::TranslateTypeOption;
|
||||
use flowy_database2::services::field::{
|
||||
ChecklistTypeOption, DateFormat, DateTypeOption, FieldBuilder, MultiSelectTypeOption,
|
||||
@@ -150,6 +151,13 @@ pub fn make_test_grid() -> DatabaseData {
|
||||
.build();
|
||||
fields.push(translate_field);
|
||||
},
|
||||
FieldType::Tag => {
|
||||
let type_option = TagTypeOption { tags: vec![] };
|
||||
let translate_field = FieldBuilder::new(field_type, type_option)
|
||||
.name("AI Tag")
|
||||
.build();
|
||||
fields.push(translate_field);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -85,6 +85,7 @@ async fn export_and_then_import_meta_csv_test() {
|
||||
FieldType::Summary => {},
|
||||
FieldType::Time => {},
|
||||
FieldType::Translate => {},
|
||||
FieldType::Tag => {},
|
||||
}
|
||||
} else {
|
||||
panic!(
|
||||
@@ -170,6 +171,7 @@ async fn history_database_import_test() {
|
||||
FieldType::Summary => {},
|
||||
FieldType::Time => {},
|
||||
FieldType::Translate => {},
|
||||
FieldType::Tag => {},
|
||||
}
|
||||
} else {
|
||||
panic!(
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use anyhow::Error;
|
||||
use client_api::entity::ai_dto::{
|
||||
SummarizeRowData, SummarizeRowParams, TranslateRowData, TranslateRowParams,
|
||||
SummarizeRowData, SummarizeRowParams, TagRowData, TagRowParams, TagRowResponse, TranslateRowData,
|
||||
TranslateRowParams,
|
||||
};
|
||||
use client_api::entity::QueryCollabResult::{Failed, Success};
|
||||
use client_api::entity::{QueryCollab, QueryCollabParams};
|
||||
@@ -13,7 +14,7 @@ use std::sync::Arc;
|
||||
use tracing::{error, instrument};
|
||||
|
||||
use flowy_database_pub::cloud::{
|
||||
CollabDocStateByOid, DatabaseCloudService, DatabaseSnapshot, SummaryRowContent,
|
||||
CollabDocStateByOid, DatabaseCloudService, DatabaseSnapshot, SummaryRowContent, TagRowContent,
|
||||
TranslateRowContent, TranslateRowResponse,
|
||||
};
|
||||
use lib_infra::future::FutureResult;
|
||||
@@ -164,4 +165,19 @@ where
|
||||
Ok(data)
|
||||
})
|
||||
}
|
||||
|
||||
fn tag_database_row(
|
||||
&self,
|
||||
workspace_id: &str,
|
||||
tag_row: TagRowContent,
|
||||
) -> FutureResult<TagRowResponse, Error> {
|
||||
let workspace_id = workspace_id.to_string();
|
||||
let try_get_client = self.inner.try_get_client();
|
||||
FutureResult::new(async move {
|
||||
let data = tag_row;
|
||||
let params = TagRowParams { workspace_id, data };
|
||||
let data = try_get_client?.tag_row(params).await?;
|
||||
Ok(data)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,12 @@
|
||||
use anyhow::Error;
|
||||
use client_api::entity::ai_dto::TagRowResponse;
|
||||
use collab::preclude::Collab;
|
||||
use collab_entity::define::{DATABASE, DATABASE_ROW_DATA, WORKSPACE_DATABASES};
|
||||
use collab_entity::CollabType;
|
||||
use yrs::{Any, MapPrelim};
|
||||
|
||||
use flowy_database_pub::cloud::{
|
||||
CollabDocStateByOid, DatabaseCloudService, DatabaseSnapshot, SummaryRowContent,
|
||||
CollabDocStateByOid, DatabaseCloudService, DatabaseSnapshot, SummaryRowContent, TagRowContent,
|
||||
TranslateRowContent, TranslateRowResponse,
|
||||
};
|
||||
use lib_infra::future::FutureResult;
|
||||
@@ -96,4 +97,12 @@ impl DatabaseCloudService for LocalServerDatabaseCloudServiceImpl {
|
||||
// TODO(lucas): local ai
|
||||
FutureResult::new(async move { Ok(TranslateRowResponse::default()) })
|
||||
}
|
||||
|
||||
fn tag_database_row(
|
||||
&self,
|
||||
workspace_id: &str,
|
||||
tag_row: TagRowContent,
|
||||
) -> FutureResult<TagRowResponse, Error> {
|
||||
FutureResult::new(async move { Ok(TagRowResponse::default()) })
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
use anyhow::Error;
|
||||
use client_api::entity::ai_dto::TagRowResponse;
|
||||
use collab_entity::CollabType;
|
||||
use tokio::sync::oneshot::channel;
|
||||
|
||||
use flowy_database_pub::cloud::{
|
||||
CollabDocStateByOid, DatabaseCloudService, DatabaseSnapshot, SummaryRowContent,
|
||||
CollabDocStateByOid, DatabaseCloudService, DatabaseSnapshot, SummaryRowContent, TagRowContent,
|
||||
TranslateRowContent, TranslateRowResponse,
|
||||
};
|
||||
use lib_dispatch::prelude::af_spawn;
|
||||
@@ -115,4 +116,12 @@ where
|
||||
) -> FutureResult<TranslateRowResponse, Error> {
|
||||
FutureResult::new(async move { Ok(TranslateRowResponse::default()) })
|
||||
}
|
||||
|
||||
fn tag_database_row(
|
||||
&self,
|
||||
workspace_id: &str,
|
||||
tag_row: TagRowContent,
|
||||
) -> FutureResult<TagRowResponse, Error> {
|
||||
FutureResult::new(async move { Ok(TagRowResponse::default()) })
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user