Added SkillTreeType enum and implemented dropdown selection in SkillTreeView

- Introduced a new `SkillTreeType` enum to represent different skill tree categories: General, Coding, Data, and Scrape/Synthesize.
- Extended the `SkillTreeType` enum to provide associated string values and JSON file names for each category.
- Refactored the `SkillTreeViewModel` to reload the skill tree data based on the selected category.
- Enhanced `SkillTreeView` by adding a positioned dropdown in the top-left corner to allow users to select and load different skill tree categories dynamically.
This commit is contained in:
hunteraraujo
2023-09-25 23:08:24 -07:00
parent 4a8da53d85
commit 3d4307a848
4 changed files with 143 additions and 63 deletions

View File

@@ -0,0 +1,38 @@
enum SkillTreeCategory {
general,
coding,
data,
scrapeSynthesize,
}
extension SkillTreeTypeExtension on SkillTreeCategory {
String get stringValue {
switch (this) {
case SkillTreeCategory.general:
return 'General';
case SkillTreeCategory.coding:
return 'Coding';
case SkillTreeCategory.data:
return 'Data';
case SkillTreeCategory.scrapeSynthesize:
return 'Scrape/Synthesize';
default:
return '';
}
}
String get jsonFileName {
switch (this) {
case SkillTreeCategory.general:
return 'general_tree_structure.json';
case SkillTreeCategory.coding:
return 'coding_tree_structure.json';
case SkillTreeCategory.data:
return 'data_tree_structure.json';
case SkillTreeCategory.scrapeSynthesize:
return 'scrape_synthesize_tree_structure.json';
default:
return '';
}
}
}

View File

@@ -3,6 +3,7 @@ import 'package:auto_gpt_flutter_client/models/benchmark/benchmark_run.dart';
import 'package:auto_gpt_flutter_client/models/benchmark/benchmark_step_request_body.dart'; import 'package:auto_gpt_flutter_client/models/benchmark/benchmark_step_request_body.dart';
import 'package:auto_gpt_flutter_client/models/benchmark/benchmark_task_request_body.dart'; import 'package:auto_gpt_flutter_client/models/benchmark/benchmark_task_request_body.dart';
import 'package:auto_gpt_flutter_client/models/benchmark/benchmark_task_status.dart'; import 'package:auto_gpt_flutter_client/models/benchmark/benchmark_task_status.dart';
import 'package:auto_gpt_flutter_client/models/skill_tree/skill_tree_category.dart';
import 'package:auto_gpt_flutter_client/models/skill_tree/skill_tree_edge.dart'; import 'package:auto_gpt_flutter_client/models/skill_tree/skill_tree_edge.dart';
import 'package:auto_gpt_flutter_client/models/skill_tree/skill_tree_node.dart'; import 'package:auto_gpt_flutter_client/models/skill_tree/skill_tree_node.dart';
import 'package:auto_gpt_flutter_client/models/step.dart'; import 'package:auto_gpt_flutter_client/models/step.dart';
@@ -41,15 +42,18 @@ class SkillTreeViewModel extends ChangeNotifier {
final Graph graph = Graph(); final Graph graph = Graph();
SugiyamaConfiguration builder = SugiyamaConfiguration(); SugiyamaConfiguration builder = SugiyamaConfiguration();
SkillTreeCategory currentSkillTreeType = SkillTreeCategory.general;
SkillTreeViewModel(this.benchmarkService, this.leaderboardService); SkillTreeViewModel(this.benchmarkService, this.leaderboardService);
Future<void> initializeSkillTree() async { Future<void> initializeSkillTree() async {
try { try {
resetState(); resetState();
String fileName = currentSkillTreeType.jsonFileName;
// Read the JSON file from assets // Read the JSON file from assets
String jsonContent = String jsonContent = await rootBundle.loadString('assets/$fileName');
await rootBundle.loadString('assets/tree_structure.json');
// Decode the JSON string // Decode the JSON string
Map<String, dynamic> decodedJson = jsonDecode(jsonContent); Map<String, dynamic> decodedJson = jsonDecode(jsonContent);
@@ -67,6 +71,7 @@ class SkillTreeViewModel extends ChangeNotifier {
} }
builder.orientation = (SugiyamaConfiguration.ORIENTATION_LEFT_RIGHT); builder.orientation = (SugiyamaConfiguration.ORIENTATION_LEFT_RIGHT);
builder.bendPointShape = CurvedBendPointShape(curveLength: 20);
notifyListeners(); notifyListeners();
@@ -206,7 +211,6 @@ class SkillTreeViewModel extends ChangeNotifier {
// Trigger the evaluation // Trigger the evaluation
final evaluationResponse = final evaluationResponse =
await benchmarkService.triggerEvaluation(task.id); await benchmarkService.triggerEvaluation(task.id);
print("Evaluation response: $evaluationResponse");
// Decode the evaluationResponse into a BenchmarkRun object // Decode the evaluationResponse into a BenchmarkRun object
BenchmarkRun benchmarkRun = BenchmarkRun.fromJson(evaluationResponse); BenchmarkRun benchmarkRun = BenchmarkRun.fromJson(evaluationResponse);
@@ -216,7 +220,7 @@ class SkillTreeViewModel extends ChangeNotifier {
await leaderboardService.submitReport(benchmarkRun); await leaderboardService.submitReport(benchmarkRun);
// Update the benchmarkStatusList based on the evaluation response // Update the benchmarkStatusList based on the evaluation response
bool successStatus = evaluationResponse['metrics']['success']; bool successStatus = benchmarkRun.metrics.success;
benchmarkStatusMap[node] = successStatus benchmarkStatusMap[node] = successStatus
? BenchmarkTaskStatus.success ? BenchmarkTaskStatus.success
: BenchmarkTaskStatus.failure; : BenchmarkTaskStatus.failure;

View File

@@ -1,3 +1,4 @@
import 'package:auto_gpt_flutter_client/models/skill_tree/skill_tree_category.dart';
import 'package:auto_gpt_flutter_client/models/skill_tree/skill_tree_node.dart'; import 'package:auto_gpt_flutter_client/models/skill_tree/skill_tree_node.dart';
import 'package:auto_gpt_flutter_client/viewmodels/skill_tree_viewmodel.dart'; import 'package:auto_gpt_flutter_client/viewmodels/skill_tree_viewmodel.dart';
import 'package:auto_gpt_flutter_client/views/skill_tree/tree_node_view.dart'; import 'package:auto_gpt_flutter_client/views/skill_tree/tree_node_view.dart';
@@ -24,72 +25,105 @@ class _SkillTreeViewState extends State<SkillTreeView> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return FutureBuilder<void>( return Stack(
future: initialization, children: [
builder: (context, snapshot) { FutureBuilder<void>(
widget.viewModel.graph.nodes.clear(); future: initialization,
widget.viewModel.graph.edges.clear(); builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) { widget.viewModel.graph.nodes.clear();
return const CircularProgressIndicator(); widget.viewModel.graph.edges.clear();
} if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator();
}
if (snapshot.hasError) { if (snapshot.hasError) {
return const Text("An error occurred"); return const Text("An error occurred");
} }
// Create Node and Edge objects for GraphView // Create Node and Edge objects for GraphView
final Map<String, Node> nodeMap = {}; final Map<String, Node> nodeMap = {};
for (var skillTreeNode in widget.viewModel.skillTreeNodes) { for (var skillTreeNode in widget.viewModel.skillTreeNodes) {
final node = Node.Id(skillTreeNode.id); final node = Node.Id(skillTreeNode.id);
widget.viewModel.graph.addNode(node); widget.viewModel.graph.addNode(node);
nodeMap[skillTreeNode.id] = node; nodeMap[skillTreeNode.id] = node;
} }
for (var skillTreeEdge in widget.viewModel.skillTreeEdges) { for (var skillTreeEdge in widget.viewModel.skillTreeEdges) {
final fromNode = nodeMap[skillTreeEdge.from]; final fromNode = nodeMap[skillTreeEdge.from];
final toNode = nodeMap[skillTreeEdge.to]; final toNode = nodeMap[skillTreeEdge.to];
if (fromNode != null && toNode != null) { if (fromNode != null && toNode != null) {
widget.viewModel.graph.addEdge(fromNode, toNode); widget.viewModel.graph.addEdge(fromNode, toNode);
} }
} }
return Scaffold( return Scaffold(
body: Column( body: Column(
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
children: [ children: [
Expanded( Expanded(
child: InteractiveViewer( child: InteractiveViewer(
constrained: false, constrained: false,
boundaryMargin: const EdgeInsets.all(100), child: SizedBox(
minScale: 0.01, width: MediaQuery.of(context).size.width,
maxScale: 5.6, height: MediaQuery.of(context).size.height,
child: GraphView( child: Align(
graph: widget.viewModel.graph, alignment: Alignment.centerLeft,
algorithm: SugiyamaAlgorithm(widget.viewModel.builder), child: GraphView(
paint: Paint() graph: widget.viewModel.graph,
..color = Colors.green algorithm:
..strokeWidth = 1 SugiyamaAlgorithm(widget.viewModel.builder),
..style = PaintingStyle.stroke, paint: Paint()
builder: (Node node) { ..color = Colors.green
String nodeId = node.key?.value as String; ..strokeWidth = 1
SkillTreeNode? skillTreeNode = ..style = PaintingStyle.stroke,
widget.viewModel.getNodeById(nodeId); builder: (Node node) {
if (skillTreeNode != null) { String nodeId = node.key?.value as String;
return TreeNodeView( SkillTreeNode? skillTreeNode =
node: skillTreeNode, widget.viewModel.getNodeById(nodeId);
selected: if (skillTreeNode != null) {
nodeId == widget.viewModel.selectedNode?.id); return TreeNodeView(
} else { node: skillTreeNode,
return const SizedBox(); // Return an empty widget if the node is not found selected: nodeId ==
} widget.viewModel.selectedNode?.id);
}, } else {
return const SizedBox(); // Return an empty widget if the node is not found
}
},
),
),
),
),
), ),
), ],
), ),
], );
},
),
Positioned(
top: 10,
left: 10,
child: Material(
type: MaterialType.transparency,
child: DropdownButton<SkillTreeCategory>(
value: widget.viewModel.currentSkillTreeType,
items: SkillTreeCategory.values.map((category) {
return DropdownMenuItem<SkillTreeCategory>(
value: category,
child: Text(category.stringValue),
);
}).toList(),
onChanged: (newValue) {
if (newValue != null) {
setState(() {
widget.viewModel.currentSkillTreeType = newValue;
widget.viewModel.initializeSkillTree();
});
}
},
),
), ),
); )
}, ],
); );
} }
} }

View File

@@ -72,6 +72,10 @@ flutter:
- assets/tree_structure.json - assets/tree_structure.json
- assets/google_logo.svg.png - assets/google_logo.svg.png
- assets/github_logo.svg.png - assets/github_logo.svg.png
- assets/general_tree_structure.json
- assets/coding_tree_structure.json
- assets/data_tree_structure.json
- assets/scrape_synthesize_tree_structure.json
# An image asset can refer to one or more resolution-specific "variants", see # An image asset can refer to one or more resolution-specific "variants", see