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:
parent
168c4a7518
commit
98713530f9
|
@ -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();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue
Block a user