feat(knowledge): add KnowledgeApi, KnowledgeRepository, wire providers
This commit is contained in:
@@ -0,0 +1,86 @@
|
|||||||
|
import 'package:dio/dio.dart';
|
||||||
|
|
||||||
|
import '../models/knowledge_item.dart';
|
||||||
|
import 'api_client.dart';
|
||||||
|
|
||||||
|
class KnowledgeApi {
|
||||||
|
final Dio _dio;
|
||||||
|
const KnowledgeApi(this._dio);
|
||||||
|
|
||||||
|
/// Fetch a page of IDs. Returns (ids, total).
|
||||||
|
Future<(List<int>, int)> fetchIds({
|
||||||
|
String? noteType,
|
||||||
|
List<String> tags = const [],
|
||||||
|
String sort = 'modified',
|
||||||
|
String? q,
|
||||||
|
int limit = 50,
|
||||||
|
int offset = 0,
|
||||||
|
}) async {
|
||||||
|
try {
|
||||||
|
final params = <String, dynamic>{
|
||||||
|
'limit': limit,
|
||||||
|
'offset': offset,
|
||||||
|
'sort': sort,
|
||||||
|
if (noteType != null) 'type': noteType,
|
||||||
|
if (tags.isNotEmpty) 'tags': tags.join(','),
|
||||||
|
if (q != null && q.isNotEmpty) 'q': q,
|
||||||
|
};
|
||||||
|
final response =
|
||||||
|
await _dio.get('/api/knowledge/ids', queryParameters: params);
|
||||||
|
final data = response.data as Map<String, dynamic>;
|
||||||
|
final ids =
|
||||||
|
(data['ids'] as List<dynamic>).map((e) => e as int).toList();
|
||||||
|
final total = data['total'] as int;
|
||||||
|
return (ids, total);
|
||||||
|
} on DioException catch (e) {
|
||||||
|
throw dioToApp(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Batch-hydrate up to 100 IDs into full items.
|
||||||
|
Future<List<KnowledgeItem>> fetchBatch(List<int> ids) async {
|
||||||
|
if (ids.isEmpty) return [];
|
||||||
|
try {
|
||||||
|
final response = await _dio.get(
|
||||||
|
'/api/knowledge/batch',
|
||||||
|
queryParameters: {'ids': ids.join(',')},
|
||||||
|
);
|
||||||
|
final data = response.data as Map<String, dynamic>;
|
||||||
|
return (data['items'] as List<dynamic>)
|
||||||
|
.map((e) => KnowledgeItem.fromJson(e as Map<String, dynamic>))
|
||||||
|
.toList();
|
||||||
|
} on DioException catch (e) {
|
||||||
|
throw dioToApp(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Per-type counts for tab labels.
|
||||||
|
Future<Map<String, int>> fetchCounts({List<String> tags = const []}) async {
|
||||||
|
try {
|
||||||
|
final params = <String, dynamic>{
|
||||||
|
if (tags.isNotEmpty) 'tags': tags.join(','),
|
||||||
|
};
|
||||||
|
final response = await _dio.get('/api/knowledge/counts',
|
||||||
|
queryParameters: params);
|
||||||
|
return (response.data as Map<String, dynamic>)
|
||||||
|
.map((k, v) => MapEntry(k, (v as num).toInt()));
|
||||||
|
} on DioException catch (e) {
|
||||||
|
throw dioToApp(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// All tags for the current type filter.
|
||||||
|
Future<List<String>> fetchTags({String? noteType}) async {
|
||||||
|
try {
|
||||||
|
final response = await _dio.get(
|
||||||
|
'/api/knowledge/tags',
|
||||||
|
queryParameters: {if (noteType != null) 'type': noteType},
|
||||||
|
);
|
||||||
|
return (response.data['tags'] as List<dynamic>)
|
||||||
|
.map((e) => e as String)
|
||||||
|
.toList();
|
||||||
|
} on DioException catch (e) {
|
||||||
|
throw dioToApp(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import '../api/knowledge_api.dart';
|
||||||
|
import '../models/knowledge_item.dart';
|
||||||
|
|
||||||
|
class KnowledgeRepository {
|
||||||
|
final KnowledgeApi _api;
|
||||||
|
const KnowledgeRepository(this._api);
|
||||||
|
|
||||||
|
Future<(List<int>, int)> fetchIds({
|
||||||
|
String? noteType,
|
||||||
|
List<String> tags = const [],
|
||||||
|
String sort = 'modified',
|
||||||
|
String? q,
|
||||||
|
int limit = 50,
|
||||||
|
int offset = 0,
|
||||||
|
}) =>
|
||||||
|
_api.fetchIds(
|
||||||
|
noteType: noteType,
|
||||||
|
tags: tags,
|
||||||
|
sort: sort,
|
||||||
|
q: q,
|
||||||
|
limit: limit,
|
||||||
|
offset: offset,
|
||||||
|
);
|
||||||
|
|
||||||
|
Future<List<KnowledgeItem>> fetchBatch(List<int> ids) =>
|
||||||
|
_api.fetchBatch(ids);
|
||||||
|
|
||||||
|
Future<Map<String, int>> fetchCounts({List<String> tags = const []}) =>
|
||||||
|
_api.fetchCounts(tags: tags);
|
||||||
|
|
||||||
|
Future<List<String>> fetchTags({String? noteType}) =>
|
||||||
|
_api.fetchTags(noteType: noteType);
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ import '../data/api/api_client.dart';
|
|||||||
import '../data/api/auth_api.dart';
|
import '../data/api/auth_api.dart';
|
||||||
import '../data/api/briefing_api.dart';
|
import '../data/api/briefing_api.dart';
|
||||||
import '../data/api/chat_api.dart';
|
import '../data/api/chat_api.dart';
|
||||||
|
import '../data/api/knowledge_api.dart';
|
||||||
import '../data/api/milestones_api.dart';
|
import '../data/api/milestones_api.dart';
|
||||||
import '../data/api/notes_api.dart';
|
import '../data/api/notes_api.dart';
|
||||||
import '../data/api/projects_api.dart';
|
import '../data/api/projects_api.dart';
|
||||||
@@ -14,6 +15,7 @@ import '../data/api/settings_api.dart';
|
|||||||
import '../data/api/tasks_api.dart';
|
import '../data/api/tasks_api.dart';
|
||||||
import '../data/repositories/auth_repository.dart';
|
import '../data/repositories/auth_repository.dart';
|
||||||
import '../data/repositories/chat_repository.dart';
|
import '../data/repositories/chat_repository.dart';
|
||||||
|
import '../data/repositories/knowledge_repository.dart';
|
||||||
import '../data/repositories/milestones_repository.dart';
|
import '../data/repositories/milestones_repository.dart';
|
||||||
import '../data/repositories/notes_repository.dart';
|
import '../data/repositories/notes_repository.dart';
|
||||||
import '../data/repositories/projects_repository.dart';
|
import '../data/repositories/projects_repository.dart';
|
||||||
@@ -83,6 +85,14 @@ final milestonesRepositoryProvider = Provider<MilestonesRepository>((ref) {
|
|||||||
return MilestonesRepository(ref.watch(milestonesApiProvider));
|
return MilestonesRepository(ref.watch(milestonesApiProvider));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
final knowledgeApiProvider = Provider<KnowledgeApi>((ref) {
|
||||||
|
return KnowledgeApi(ref.watch(dioProvider));
|
||||||
|
});
|
||||||
|
|
||||||
|
final knowledgeRepositoryProvider = Provider<KnowledgeRepository>((ref) {
|
||||||
|
return KnowledgeRepository(ref.watch(knowledgeApiProvider));
|
||||||
|
});
|
||||||
|
|
||||||
final briefingApiProvider = Provider<BriefingApi>((ref) {
|
final briefingApiProvider = Provider<BriefingApi>((ref) {
|
||||||
return BriefingApi(ref.watch(dioProvider));
|
return BriefingApi(ref.watch(dioProvider));
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user