1
0
mirror of https://github.com/go-vikunja/app synced 2024-06-05 03:59:48 +00:00

added project list page with expandable sublists

This commit is contained in:
Benimautner 2023-07-22 23:31:28 +02:00
parent 6f32e1ff38
commit 1c523d929c
2 changed files with 85 additions and 55 deletions

View File

@ -1,3 +1,4 @@
import 'package:after_layout/after_layout.dart'; import 'package:after_layout/after_layout.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -10,8 +11,7 @@ import '../../models/project.dart';
class ProjectOverviewPage extends StatefulWidget { class ProjectOverviewPage extends StatefulWidget {
@override @override
_ProjectOverviewPageState createState() => _ProjectOverviewPageState createState() => new _ProjectOverviewPageState();
new _ProjectOverviewPageState();
} }
class _ProjectOverviewPageState extends State<ProjectOverviewPage> class _ProjectOverviewPageState extends State<ProjectOverviewPage>
@ -30,67 +30,96 @@ class _ProjectOverviewPageState extends State<ProjectOverviewPage>
_loadProjects(); _loadProjects();
} }
Widget createProjectTile(Project project, int level){ List<int> expandedList = [];
List<Widget> children = addProjectChildren(project, level);
EdgeInsets insets = EdgeInsets.fromLTRB(level * 20 + 10, 0, 0, 0); Widget createProjectTile(Project project, int level) {
if(children.length == 0) { EdgeInsets insets = EdgeInsets.fromLTRB(level * 10 + 10, 0, 0, 0);
return new ListTile(
leading: const Icon(Icons.folder), bool expanded = expandedList.contains(project.id);
title: new Text(project.title), Widget icon;
contentPadding: insets,
); List<Widget>? children = addProjectChildren(project, level+1);
bool no_children = children.length == 0;
if(no_children) {
icon = Icon(Icons.list);
} else { } else {
return new ExpansionTile( if (expanded) {
leading: const Icon(Icons.folder), icon = Icon(Icons.arrow_drop_down_sharp);
title: new Text(project.title), } else {
children: children, children = null;
tilePadding: insets icon = Icon(Icons.arrow_right_sharp);
//onTap: () => _onSelectItem(i), }
);
} }
}
return Column(children: [
ListTile(
onTap: () {
setState(() {
_onSelectItem(project);
});
},
contentPadding: insets,
leading: IconButton(
disabledColor: Theme.of(context).unselectedWidgetColor,
icon: icon,
onPressed: !no_children ? () {
setState(() {
if (expanded)
expandedList.remove(project.id);
else
expandedList.add(project.id);
});
} : null,
),
title: new Text(project.title),
//onTap: () => _onSelectItem(i),
),
...?children
]);
}
List<Widget> addProjectChildren(Project project, level) { List<Widget> addProjectChildren(Project project, level) {
Iterable<Project> children = _projects.where((element) => element.parentProjectId == project.id); Iterable<Project> children =
_projects.where((element) => element.parentProjectId == project.id);
List<Widget> widgets = []; List<Widget> widgets = [];
children.forEach((element) {widgets.add(createProjectTile(element, level + 1));}); children.forEach((element) {
widgets.add(createProjectTile(element, level + 1));
});
return widgets; return widgets;
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
List<Widget> projectList = <Widget>[]; List<Widget> projectList = <Widget>[];
_projects _projects.asMap().forEach((i, project) {
.asMap() if (project.parentProjectId != 0) return;
.forEach((i, project) { projectList.add(createProjectTile(project, 0));
if(project.parentProjectId != 0) });
return;
projectList.add(createProjectTile(project, 0));
});
if(_selectedDrawerIndex > -1) { if (_selectedDrawerIndex > -1) {
return new WillPopScope( return new WillPopScope(
child: ProjectPage(project: _projects[_selectedDrawerIndex]), child: ProjectPage(project: _projects[_selectedDrawerIndex]),
onWillPop: () async {setState(() { onWillPop: () async {
_selectedDrawerIndex = -2; setState(() {
_selectedDrawerIndex = -2;
});
return false;
}); });
return false;});
} }
return Scaffold( return Scaffold(
body: body: this._loading
this._loading
? Center(child: CircularProgressIndicator()) ? Center(child: CircularProgressIndicator())
: : RefreshIndicator(
RefreshIndicator( child: ListView(
child: ListView( padding: EdgeInsets.zero,
padding: EdgeInsets.zero, children:
children: ListTile.divideTiles( ListTile.divideTiles(context: context, tiles: projectList)
context: context, tiles: projectList) .toList()),
.toList()), onRefresh: _loadProjects,
onRefresh: _loadProjects, ),
),
floatingActionButton: Builder( floatingActionButton: Builder(
builder: (context) => FloatingActionButton( builder: (context) => FloatingActionButton(
onPressed: () => _addProjectDialog(context), onPressed: () => _addProjectDialog(context),
@ -110,12 +139,14 @@ class _ProjectOverviewPageState extends State<ProjectOverviewPage>
}); });
} }
_onSelectItem(int index) { _onSelectItem(Project project) {
Navigator.push(context, Navigator.push(
context,
MaterialPageRoute( MaterialPageRoute(
builder: (buildContext) => ProjectPage( builder: (buildContext) => ProjectPage(
project: _projects[index], project: project,
),)); ),
));
//setState(() => _selectedDrawerIndex = index); //setState(() => _selectedDrawerIndex = index);
} }
@ -123,10 +154,10 @@ class _ProjectOverviewPageState extends State<ProjectOverviewPage>
showDialog( showDialog(
context: context, context: context,
builder: (_) => AddDialog( builder: (_) => AddDialog(
onAdd: (name) => _addProject(name, context), onAdd: (name) => _addProject(name, context),
decoration: new InputDecoration( decoration: new InputDecoration(
labelText: 'Project', hintText: 'eg. Personal Project'), labelText: 'Project', hintText: 'eg. Personal Project'),
)); ));
} }
_addProject(String name, BuildContext context) { _addProject(String name, BuildContext context) {
@ -144,6 +175,6 @@ class _ProjectOverviewPageState extends State<ProjectOverviewPage>
content: Text('The project was created successfully!'), content: Text('The project was created successfully!'),
)); ));
}).catchError((error) => showDialog( }).catchError((error) => showDialog(
context: context, builder: (context) => ErrorDialog(error: error))); context: context, builder: (context) => ErrorDialog(error: error)));
} }
} }

View File

@ -16,8 +16,7 @@ class ProjectPage extends StatefulWidget {
class _ProjectPageState extends State<ProjectPage> { class _ProjectPageState extends State<ProjectPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
// TODO: implement build return Scaffold(body: Text(widget.project.title),);
return Scaffold();
} }
} }