1
0
mirror of https://github.com/go-vikunja/app synced 2024-06-01 02:06:51 +00:00

added main overview page

This commit is contained in:
benimautner 2022-04-15 20:14:04 +02:00
parent 168c4a7518
commit 98713530f9
7 changed files with 137 additions and 13 deletions

View File

@ -31,4 +31,15 @@ class TaskAPIService extends APIService implements TaskService {
.post('/tasks/${task.id}', body: task.toJSON())
.then((map) => Task.fromJson(map));
}
@override
Future<List<Task>> getByOptions(TaskServiceOptions options) {
String optionString = options.getOptions();
return client
.get('/tasks/all?$optionString')
.then((value) {
return value.map<Task>((taskJson) => Task.fromJson(taskJson)).toList();
});
}
}

View File

@ -45,6 +45,8 @@ class VikunjaGlobalState extends State<VikunjaGlobal> {
ListService get listService => new ListAPIService(client, _storage);
TaskServiceOptions get taskServiceOptions => new TaskServiceOptions();
@override
void initState() {
super.initState();

View File

@ -1,14 +1,17 @@
import 'package:vikunja_app/models/user.dart';
import 'package:meta/meta.dart';
import 'list.dart';
class Task {
int id;
int id, list_id;
DateTime created, updated, due;
List<DateTime> reminders;
String title, description;
bool done;
User owner;
bool loading = false;
TaskList list;
Task(
{@required this.id,
@ -20,7 +23,8 @@ class Task {
this.description,
@required this.done,
@required this.owner,
this.loading});
this.loading,
this.list_id});
Task.fromJson(Map<String, dynamic> json)
: id = json['id'],
@ -34,6 +38,7 @@ class Task {
description = json['description'],
title = json['title'],
done = json['done'],
list_id = json['list_id'],
owner = json['created_by'] == null ? null : User.fromJson(json['created_by']);
toJSON() => {
@ -46,6 +51,7 @@ class Task {
'description': description,
'title': title,
'done': done ?? false,
'created_by': owner?.toJSON()
'created_by': owner?.toJSON(),
'list_id': list_id
};
}

View File

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:vikunja_app/global.dart';
import '../components/AddDialog.dart';
import '../components/TaskTile.dart';
import '../models/task.dart';
class LandingPage extends StatefulWidget {
@ -12,27 +13,42 @@ class LandingPage extends StatefulWidget {
class LandingPageState extends State<LandingPage> {
int defaultList;
List<Task> _list;
@override
void initState() {
Future.delayed(Duration.zero, () =>
VikunjaGlobal.of(context).listService.getDefaultList().then((value) => setState(() => defaultList = value == null ? null : int.tryParse(value))));
super.initState();
}
@override
Widget build(BuildContext context) {
VikunjaGlobal.of(context).listService.getDefaultList().then((value) => setState(() => defaultList = value == null ? null : int.tryParse(value)));
if(_list == null)
_loadList(context);
return new Scaffold(
body: Container(
padding: EdgeInsets.only(left: 16.0),
child: new Column(
body: new Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
new Container(
padding: EdgeInsets.only(top: 32.0),
child: new Text(
// VikunjaGlobal.of(context).taskServiceOptions.getOptions()
// TaskServiceOptionSortBy.id.name
'Welcome to Vikunja',
style: Theme.of(context).textTheme.headline4,
),
),
new Text('Please select a namespace by tapping the ☰ icon.',
style: Theme.of(context).textTheme.subtitle1),
//new Text('Please select a namespace by tapping the ☰ icon.',
// style: Theme.of(context).textTheme.subtitle1),
_list != null ? new Expanded(child: ListView(
scrollDirection: Axis.vertical,
shrinkWrap: true,
padding: EdgeInsets.symmetric(vertical: 8.0),
children: ListTile.divideTiles(
context: context, tiles: _listTasks(context)).toList(),
)) : new Center(child: CircularProgressIndicator())
],
)
),
),
floatingActionButton: Builder(
builder: (context) =>
defaultList == null ?
@ -69,6 +85,40 @@ class LandingPageState extends State<LandingPage> {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('The task was added successfully!'),
));
_loadList(context).then((value) => setState((){}));
});
}
List<Widget> _listTasks(BuildContext context) {
var tasks = (_list.map((task) => _buildTile(task, context)) ?? []).toList();
//tasks.addAll(_loadingTasks.map(_buildLoadingTile));
return tasks;
}
TaskTile _buildTile(Task task, BuildContext context) {
// key: UniqueKey() seems like a weird workaround to fix the loading issue
// is there a better way?
return TaskTile(key: UniqueKey(), task: task,onEdit: () => _loadList(context), showInfo: true,);
}
Future<void> _loadList(BuildContext context) {
_list = [];
return VikunjaGlobal.of(context)
.taskService
.getByOptions(VikunjaGlobal.of(context).taskServiceOptions)
.then((taskList) {
VikunjaGlobal.of(context)
.listService
.getAll()
.then((lists) {
taskList.forEach((task) {task.list = lists.firstWhere((element) => element.id == task.list_id);});
setState(() {
_list = taskList;
});
});
});
}
}

View File

@ -158,7 +158,7 @@ class _TaskEditPageState extends State<TaskEditPage> {
DateTime date = await showDialog(
context: context,
builder: (_) => DatePickerDialog(
initialDate: _due,
initialDate: _due.year > 1 ? _due : DateTime.now(),
firstDate: DateTime(0),
lastDate: DateTime(9999),
initialCalendarMode: DatePickerMode.day,

View File

@ -172,6 +172,12 @@ class MockedTaskService implements TaskService {
// TODO: implement get
throw UnimplementedError();
}
@override
Future<List<Task>> getByOptions(TaskServiceOptions options) {
// TODO: implement getByOptions
throw UnimplementedError();
}
}
class MockedUserService implements UserService {

View File

@ -5,6 +5,54 @@ import 'package:vikunja_app/models/namespace.dart';
import 'package:vikunja_app/models/task.dart';
import 'package:vikunja_app/models/user.dart';
enum TaskServiceOptionSortBy {id, title, description, done, done_at, due_date, created_by_id, list_id, repeat_after, priority, start_date, end_date, hex_color, percent_done, uid, created, updated}
enum TaskServiceOptionOrderBy {asc,desc}
enum TaskServiceOptionFilterBy {done}
enum TaskServiceOptionFilterValue {enum_true,enum_false}
class TaskServiceOption<T> {
String name;
List<T> possibleValues;
dynamic value;
dynamic defValue;
TaskServiceOption(
this.name,
this.possibleValues,
this.value
);
String getValue() {
return value.toString().split('.').last.replaceAll('enum_', '');
}
}
class TaskServiceOptions {
List<TaskServiceOption> options = [
TaskServiceOption<TaskServiceOptionSortBy>("sort_by",TaskServiceOptionSortBy.values, TaskServiceOptionSortBy.due_date),
TaskServiceOption<TaskServiceOptionOrderBy>("order_by",TaskServiceOptionOrderBy.values, TaskServiceOptionOrderBy.desc),
TaskServiceOption<TaskServiceOptionFilterBy>("filter_by",TaskServiceOptionFilterBy.values, TaskServiceOptionFilterBy.done),
TaskServiceOption<TaskServiceOptionFilterValue>("filter_value",TaskServiceOptionFilterValue.values, TaskServiceOptionFilterValue.enum_false),
];
void setOption(TaskServiceOption option, dynamic value) {
options.firstWhere((element) => element.name == option.name).value = value;
}
String getOptions() {
String result = '';
for(TaskServiceOption option in options) {
dynamic value = option.getValue();
if(result.isNotEmpty)
result += '&';
/*if(option.value is List) {
for(dynamic value in option.value) {
result += option.name+'[]='+value.g;
}*/
result += option.name+'=' + value;
}
return result;
}
}
abstract class NamespaceService {
Future<List<Namespace>> getAll();
Future<Namespace> get(int namespaceId);
@ -31,7 +79,8 @@ abstract class TaskService {
Future<Task> update(Task task);
Future delete(int taskId);
Future<Task> add(int listId, Task task);
}
Future<List<Task>> getByOptions(TaskServiceOptions options);
}
abstract class UserService {
Future<UserTokenPair> login(String username, password);