added fields to task view, changed icon of task editing.

This commit is contained in:
Benimautner 2024-02-16 19:11:16 +01:00
parent aa0f56231f
commit 1ef9ed4e67
6 changed files with 103 additions and 14 deletions

View File

@ -1,18 +1,30 @@
import 'package:datetime_picker_formfield/datetime_picker_formfield.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_widget_from_html/flutter_widget_from_html.dart';
import 'package:provider/provider.dart';
import 'package:vikunja_app/utils/priority.dart';
import '../models/label.dart';
import '../models/task.dart';
import '../pages/list/task_edit.dart';
import '../stores/project_store.dart';
import '../theme/constants.dart';
import 'label.dart';
class TaskBottomSheet extends StatefulWidget {
final Task task;
final bool showInfo;
final bool loading;
final Function onEdit;
final ValueSetter<bool>? onMarkedAsDone;
final ProjectProvider taskState;
const TaskBottomSheet({
Key? key,
required this.task,
required this.onEdit,
required this.taskState,
this.loading = false,
this.showInfo = false,
this.onMarkedAsDone,
@ -35,28 +47,96 @@ class TaskBottomSheetState extends State<TaskBottomSheet> {
@override
Widget build(BuildContext context) {
ThemeData theme = Theme.of(context);
return Container(
height: MediaQuery.of(context).size.height * 0.9,
child: Center(
child: Padding(
padding: EdgeInsets.fromLTRB(10, 10, 10, 10),
child: Padding(
padding: EdgeInsets.fromLTRB(20, 10, 10, 20),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
// Title and edit button
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(_currentTask.title),
BackButton(),
Text(_currentTask.title, style: theme.textTheme.headlineLarge),
IconButton(onPressed: () {
Navigator.push<Task>(
context,
MaterialPageRoute(
builder: (buildContext) => TaskEditPage(
task: _currentTask,
taskState: widget.taskState,
),
),
)
.then((task) => setState(() {
if (task != null) _currentTask = task;
}))
.whenComplete(() => widget.onEdit());
}, icon: Icon(Icons.edit)),
],
),
Wrap(
spacing: 10,
children: _currentTask.labels.map((Label label) {
return LabelComponent(
label: label,
);
}).toList()),
// description with html rendering
Text("Description", style: theme.textTheme.headlineSmall),
Padding(padding: EdgeInsets.fromLTRB(10, 0, 0, 0),
child: HtmlWidget(_currentTask.description.isNotEmpty ? _currentTask.description : "No description"),
),
// Due date
Row(
children: [
Icon(Icons.access_time),
Padding(padding: EdgeInsets.fromLTRB(10, 0, 0, 0)),
Text(_currentTask.dueDate != null ? vDateFormatShort.format(_currentTask.dueDate!.toLocal()) : "No due date"),
],
),
// start date
Row(
children: [
Icon(Icons.play_arrow_rounded),
Padding(padding: EdgeInsets.fromLTRB(10, 0, 0, 0)),
Text(_currentTask.startDate != null ? vDateFormatShort.format(_currentTask.startDate!.toLocal()) : "No start date"),
],
),
// end date
Row(
children: [
Icon(Icons.stop_rounded),
Padding(padding: EdgeInsets.fromLTRB(10, 0, 0, 0)),
Text(_currentTask.endDate != null ? vDateFormatShort.format(_currentTask.endDate!.toLocal()) : "No end date"),
],
),
// priority
Row(
children: [
Icon(Icons.priority_high),
Padding(padding: EdgeInsets.fromLTRB(10, 0, 0, 0)),
Text(_currentTask.priority != null ? priorityToString(_currentTask.priority) : "No priority"),
],
),
// progress
Row(
children: [
Icon(Icons.percent),
Padding(padding: EdgeInsets.fromLTRB(10, 0, 0, 0)),
Text(_currentTask.percent_done != null ? (_currentTask.percent_done! * 100).toInt().toString() + "%" : "Unset"),
],
),
HtmlWidget(_currentTask.description),
],
),
)
),
);
}

View File

@ -92,7 +92,7 @@ class TaskTileState extends State<TaskTile> with AutomaticKeepAliveClientMixin {
? null
: HtmlWidget(_currentTask.description),
trailing: IconButton(
icon: Icon(Icons.settings),
icon: Icon(Icons.edit),
onPressed: () {},
),
);
@ -110,7 +110,7 @@ class TaskTileState extends State<TaskTile> with AutomaticKeepAliveClientMixin {
showModalBottomSheet<void>(
context: context,
builder: (BuildContext context) {
return TaskBottomSheet(task: widget.task);
return TaskBottomSheet(task: widget.task, onEdit: widget.onEdit, taskState: taskState);
});
},
title: widget.showInfo
@ -137,7 +137,7 @@ class TaskTileState extends State<TaskTile> with AutomaticKeepAliveClientMixin {
},
),
trailing: IconButton(
icon: Icon(Icons.settings),
icon: Icon(Icons.edit),
onPressed: () {
Navigator.push<Task>(
context,

View File

@ -3,9 +3,9 @@ import 'package:vikunja_app/models/label.dart';
class LabelComponent extends StatelessWidget {
final Label label;
final VoidCallback onDelete;
final VoidCallback? onDelete;
const LabelComponent({Key? key, required this.label, required this.onDelete})
const LabelComponent({Key? key, required this.label, this.onDelete})
: super(key: key);
@override

View File

@ -20,6 +20,7 @@ class Task {
final bool done;
Color? color;
final double? kanbanPosition;
final double? percent_done;
final User createdBy;
Duration? repeatAfter;
final List<Task> subtasks;
@ -45,6 +46,7 @@ class Task {
this.repeatAfter,
this.color,
this.kanbanPosition,
this.percent_done,
this.subtasks = const [],
this.labels = const [],
this.attachments = const [],
@ -90,6 +92,9 @@ class Task {
kanbanPosition = json['kanban_position'] is int
? json['kanban_position'].toDouble()
: json['kanban_position'],
percent_done = json['percent_done'] is int
? json['percent_done'].toDouble()
: json['percent_done'],
labels = json['labels'] != null
? (json['labels'] as List<dynamic>)
.map((label) => Label.fromJson(label))
@ -128,6 +133,7 @@ class Task {
'repeat_after': repeatAfter?.inSeconds,
'hex_color': color?.value.toRadixString(16).padLeft(8, '0').substring(2),
'kanban_position': kanbanPosition,
'percent_done': percent_done,
'project_id': projectId,
'labels': labels.map((label) => label.toJSON()).toList(),
'subtasks': subtasks.map((subtask) => subtask.toJSON()).toList(),
@ -157,6 +163,7 @@ class Task {
bool? done,
Color? color,
double? kanbanPosition,
double? percent_done,
User? createdBy,
Duration? repeatAfter,
List<Task>? subtasks,
@ -182,6 +189,7 @@ class Task {
done: done ?? this.done,
color: color ?? this.color,
kanbanPosition: kanbanPosition ?? this.kanbanPosition,
percent_done: percent_done ?? this.percent_done,
createdBy: createdBy ?? this.createdBy,
repeatAfter: repeatAfter ?? this.repeatAfter,
subtasks: subtasks ?? this.subtasks,

View File

@ -252,7 +252,7 @@ class _TaskEditPageState extends State<TaskEditPage> {
_reminderDates.add(DateTime(0));
var currentIndex = _reminderDates.length - 1;
// FIXME: Why does putting this into a row fails?
// FIXME: Why does putting this into a row fail?
setState(() => _reminderInputs.add(
VikunjaDateTimePicker(
label: 'Reminder',

View File

@ -30,4 +30,5 @@ const vStandardVerticalPadding = EdgeInsets.symmetric(vertical: 5.0);
const vStandardHorizontalPadding = EdgeInsets.symmetric(horizontal: 5.0);
const vStandardPadding = EdgeInsets.symmetric(horizontal: 5.0, vertical: 5.0);
var vDateFormatLong = DateFormat("EEEE, MMMM d, yyyy 'at' H:mm");
var vDateFormatLong = DateFormat("EEEE, MMMM d, yyyy 'at' H:mm");
var vDateFormatShort = DateFormat("d MMM yyyy, H:mm");