Projects Details (error)
This commit is contained in:
BIN
images/project.png
Normal file
BIN
images/project.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 177 KiB |
@@ -78,8 +78,12 @@ class _ActivitiesState extends State<Activities> {
|
|||||||
label: Text("New Activity"),
|
label: Text("New Activity"),
|
||||||
icon: Icon(Icons.add)),
|
icon: Icon(Icons.add)),
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
|
toolbarHeight: (searching) ? 90 : null,
|
||||||
title: (searching)
|
title: (searching)
|
||||||
? Row(
|
? Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
mainAxisSize: MainAxisSize.max,
|
mainAxisSize: MainAxisSize.max,
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
@@ -101,6 +105,9 @@ class _ActivitiesState extends State<Activities> {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
),
|
||||||
|
Text('searched time : ${Main.MinutesToTimeString(searchTime)}',style: TextStyle(fontSize: 15),)
|
||||||
|
],
|
||||||
)
|
)
|
||||||
: Row(
|
: Row(
|
||||||
mainAxisSize: MainAxisSize.max,
|
mainAxisSize: MainAxisSize.max,
|
||||||
@@ -175,7 +182,7 @@ class _ActivitiesState extends State<Activities> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int searchTime = 0;
|
||||||
List<Widget> PrintTasks() {
|
List<Widget> PrintTasks() {
|
||||||
List<Widget> _tasks = [];
|
List<Widget> _tasks = [];
|
||||||
print('Priting cats : ' + User.taskTypes.length.toString());
|
print('Priting cats : ' + User.taskTypes.length.toString());
|
||||||
@@ -211,6 +218,7 @@ class _ActivitiesState extends State<Activities> {
|
|||||||
}
|
}
|
||||||
print(productivtyActs);
|
print(productivtyActs);
|
||||||
//for (var element in User.activities) {
|
//for (var element in User.activities) {
|
||||||
|
searchTime=0;
|
||||||
for(int i =0; i < User.activities.length; i++){
|
for(int i =0; i < User.activities.length; i++){
|
||||||
Activity element =User.activities[i];
|
Activity element =User.activities[i];
|
||||||
if(searching){
|
if(searching){
|
||||||
@@ -219,6 +227,7 @@ class _ActivitiesState extends State<Activities> {
|
|||||||
bool matchCategory = element.taskType.cat!.name.toLowerCase().contains(searchController.text.toLowerCase());
|
bool matchCategory = element.taskType.cat!.name.toLowerCase().contains(searchController.text.toLowerCase());
|
||||||
if(matchMetadata || matchTaskType || matchCategory){
|
if(matchMetadata || matchTaskType || matchCategory){
|
||||||
//Good to go
|
//Good to go
|
||||||
|
searchTime += element.endTime.difference(element.startTime).inMinutes;
|
||||||
}else{
|
}else{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -464,10 +473,19 @@ class _ActivitiesState extends State<Activities> {
|
|||||||
SizedBox(
|
SizedBox(
|
||||||
width: 20,
|
width: 20,
|
||||||
),
|
),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
(activity.taskType.relatedProject!= null) ?Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 2),
|
||||||
|
decoration: BoxDecoration(borderRadius: BorderRadius.circular(10), color: Colors.black26),
|
||||||
|
child: Text(activity.taskType.relatedProject!.name ?? 'n/a')) : Container(),
|
||||||
|
SizedBox(width: 10,),
|
||||||
Container(
|
Container(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 2),
|
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 2),
|
||||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(10), color: (productive) ? Colors.green : Colors.red),
|
decoration: BoxDecoration(borderRadius: BorderRadius.circular(10), color: (productive) ? Colors.green : Colors.red),
|
||||||
child: Text(activity.taskType.cat?.name ?? 'n/a'))
|
child: Text(activity.taskType.cat?.name ?? 'n/a')),
|
||||||
|
],
|
||||||
|
)
|
||||||
// Icon(Icons.circle,
|
// Icon(Icons.circle,
|
||||||
// color: (productive)
|
// color: (productive)
|
||||||
// ? Colors.green
|
// ? Colors.green
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ class HourglassPainter extends CustomPainter{
|
|||||||
..strokeCap=StrokeCap.round
|
..strokeCap=StrokeCap.round
|
||||||
..strokeWidth=1;
|
..strokeWidth=1;
|
||||||
|
|
||||||
print('bottom: $bottomStartHeight, top: $bottomEndHeight');
|
// print('bottom: $bottomStartHeight, top: $bottomEndHeight');
|
||||||
|
|
||||||
canvas.drawPath(fallingSand, contentPainter);
|
canvas.drawPath(fallingSand, contentPainter);
|
||||||
canvas.drawPath(topContent, contentPainter);
|
canvas.drawPath(topContent, contentPainter);
|
||||||
|
|||||||
@@ -225,6 +225,7 @@ class _NewProject2State extends State<NewProject2> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|
||||||
List<Widget> stepsWidgets = printSteps();
|
List<Widget> stepsWidgets = printSteps();
|
||||||
|
etaHours =0;
|
||||||
steps.forEach((element) {
|
steps.forEach((element) {
|
||||||
etaHours+=element.eta;
|
etaHours+=element.eta;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,16 +3,19 @@ import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
|
|||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:tasktracker/NewCategory.dart';
|
import 'package:tasktracker/NewCategory.dart';
|
||||||
import 'package:tasktracker/NewProject.dart';
|
import 'package:tasktracker/NewProject.dart';
|
||||||
|
import 'Data.dart';
|
||||||
import 'User.dart' as User;
|
import 'User.dart' as User;
|
||||||
|
|
||||||
DateFormat dateFormat = DateFormat("yyyy-MM-dd HH:mm:ss");
|
DateFormat dateFormat = DateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
DateFormat durationFormat = DateFormat("HH:mm:ss");
|
DateFormat durationFormat = DateFormat("HH:mm:ss");
|
||||||
|
|
||||||
class NewTask extends StatefulWidget {
|
class NewTask extends StatefulWidget {
|
||||||
const NewTask({Key? key}) : super(key: key);
|
NewTask({Key? key, this.t_cat, this.t_name, this.t_relProj}) : super(key: key);
|
||||||
|
late String? t_name;
|
||||||
|
late String? t_cat;
|
||||||
|
late String? t_relProj;
|
||||||
@override
|
@override
|
||||||
_NewTaskState createState() => _NewTaskState();
|
_NewTaskState createState() => _NewTaskState(t_cat: t_cat, t_name: t_name, t_relProj: t_relProj);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> getCategoryNames(){
|
List<String> getCategoryNames(){
|
||||||
@@ -39,6 +42,19 @@ List<String> getProjectNames(){
|
|||||||
String selectedCat = User.categories[0].name;
|
String selectedCat = User.categories[0].name;
|
||||||
String selectedProj = "None";
|
String selectedProj = "None";
|
||||||
class _NewTaskState extends State<NewTask> {
|
class _NewTaskState extends State<NewTask> {
|
||||||
|
bool editing = false;
|
||||||
|
String? oldName;
|
||||||
|
_NewTaskState({String? t_name, String? t_cat, String? t_relProj}){
|
||||||
|
if(t_name !=null && t_cat != null){
|
||||||
|
editing = true;
|
||||||
|
oldName = t_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
nameController.text = t_name ?? '';
|
||||||
|
selectedCat = t_cat ?? User.categories[0].name;
|
||||||
|
selectedProj = t_relProj ?? 'None';
|
||||||
|
}
|
||||||
|
|
||||||
TextEditingController nameController = TextEditingController();
|
TextEditingController nameController = TextEditingController();
|
||||||
bool productive = true;
|
bool productive = true;
|
||||||
|
|
||||||
@@ -46,7 +62,7 @@ class _NewTaskState extends State<NewTask> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
List<String> cats = getCategoryNames();
|
List<String> cats = getCategoryNames();
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(title: Text('New Task Type')),
|
appBar: AppBar(title: Text('${(editing) ? 'Edit ' : 'New '} Task Type')),
|
||||||
body: Container(
|
body: Container(
|
||||||
height: MediaQuery.of(context).size.height,
|
height: MediaQuery.of(context).size.height,
|
||||||
child: Column(
|
child: Column(
|
||||||
@@ -99,7 +115,7 @@ class _NewTaskState extends State<NewTask> {
|
|||||||
child: Text(value),
|
child: Text(value),
|
||||||
);
|
);
|
||||||
}).toList(),
|
}).toList(),
|
||||||
onChanged: (String? _value) {
|
onChanged:(selectedProj == 'None') ? (String? _value) {
|
||||||
if(_value != null) {
|
if(_value != null) {
|
||||||
if (_value.contains("+Add New Category")) {
|
if (_value.contains("+Add New Category")) {
|
||||||
Navigator.of(context).push(MaterialPageRoute(builder: (context)=>NewCategory()));
|
Navigator.of(context).push(MaterialPageRoute(builder: (context)=>NewCategory()));
|
||||||
@@ -110,7 +126,7 @@ class _NewTaskState extends State<NewTask> {
|
|||||||
setState(() {
|
setState(() {
|
||||||
|
|
||||||
});
|
});
|
||||||
})),
|
} : null)),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.fromLTRB(0, 20, 0, 10),
|
padding: const EdgeInsets.fromLTRB(0, 20, 0, 10),
|
||||||
child: Text('Related Project'),
|
child: Text('Related Project'),
|
||||||
@@ -138,7 +154,7 @@ class _NewTaskState extends State<NewTask> {
|
|||||||
child: Text(value),
|
child: Text(value),
|
||||||
);
|
);
|
||||||
}).toList(),
|
}).toList(),
|
||||||
onChanged: (String? _value) {
|
onChanged: (String? _value) async{
|
||||||
if(_value != null) {
|
if(_value != null) {
|
||||||
if (_value.contains("+Add New Project")) {
|
if (_value.contains("+Add New Project")) {
|
||||||
Navigator.of(context).push(MaterialPageRoute(builder: (context)=>NewProject()));
|
Navigator.of(context).push(MaterialPageRoute(builder: (context)=>NewProject()));
|
||||||
@@ -146,6 +162,13 @@ class _NewTaskState extends State<NewTask> {
|
|||||||
selectedProj = _value!;
|
selectedProj = _value!;
|
||||||
if(_value.contains("None")){
|
if(_value.contains("None")){
|
||||||
|
|
||||||
|
}else{
|
||||||
|
Project? relProj = await User.getProjectFromId(selectedProj);
|
||||||
|
if(relProj==null){
|
||||||
|
|
||||||
|
}else{
|
||||||
|
selectedCat = relProj.cat!.name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -195,10 +218,14 @@ class _NewTaskState extends State<NewTask> {
|
|||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
|
if(editing){
|
||||||
|
edit_action();
|
||||||
|
}else {
|
||||||
add_action();
|
add_action();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
child: Text('Add Task Type',
|
child: Text((editing) ? 'Apply' : 'Add Task Type',
|
||||||
style: TextStyle(fontSize: 20))))),
|
style: TextStyle(fontSize: 20))))),
|
||||||
],
|
],
|
||||||
))
|
))
|
||||||
@@ -217,6 +244,19 @@ class _NewTaskState extends State<NewTask> {
|
|||||||
return route.isFirst;
|
return route.isFirst;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void edit_action() async{
|
||||||
|
String catName = nameController.value.text;
|
||||||
|
print('editing Task Type $oldName => : $catName, $selectedCat');
|
||||||
|
if(catName.length< 2){
|
||||||
|
showAlertDialog(context, 'Category needs a name', 'Please enter a name for this category');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await User.UserOperations.editTaskType(oldName! ,catName,selectedCat,relatedProject: (selectedProj == 'None') ? '' : selectedProj);
|
||||||
|
Navigator.of(context).popUntil((route){
|
||||||
|
return route.isFirst;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String _printDuration(Duration duration) {
|
String _printDuration(Duration duration) {
|
||||||
|
|||||||
142
lib/ProjectDetails.dart
Normal file
142
lib/ProjectDetails.dart
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
|
|
||||||
|
import 'Data.dart';
|
||||||
|
|
||||||
|
class ProjectDetails extends StatefulWidget {
|
||||||
|
const ProjectDetails({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<ProjectDetails> createState() => _ProjectDetailsState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ProjectDetailsState extends State<ProjectDetails> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
|
||||||
|
List<Widget> stepsWidgets = printSteps();
|
||||||
|
etaHours =0;
|
||||||
|
steps.forEach((element) {
|
||||||
|
etaHours+=element.eta;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(title: Row(
|
||||||
|
children: [
|
||||||
|
FaIcon(FontAwesomeIcons.projectDiagram),
|
||||||
|
SizedBox(width: 15,),
|
||||||
|
Text('This app'),
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
body: Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
|
||||||
|
Card(child:LimitedBox(
|
||||||
|
maxHeight: 300,
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
color: Colors.white10,
|
||||||
|
),
|
||||||
|
padding: EdgeInsets.all(10),
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
scrollDirection: Axis.vertical,
|
||||||
|
child: (stepsWidgets.isNotEmpty) ? Container(
|
||||||
|
child: Column(
|
||||||
|
children: stepsWidgets,
|
||||||
|
),
|
||||||
|
) : Container(
|
||||||
|
|
||||||
|
height: 20,
|
||||||
|
child: Text('Click on + to add steps')
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
),),
|
||||||
|
|
||||||
|
Card(child:Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Text('Actions'),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
|
children: [
|
||||||
|
ElevatedButton(onPressed: (){}, child: Row(
|
||||||
|
children: [
|
||||||
|
FaIcon(FontAwesomeIcons.edit),
|
||||||
|
SizedBox(width: 10,),
|
||||||
|
Text('Edit'),
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
ElevatedButton(style:ElevatedButton.styleFrom(
|
||||||
|
primary: Colors.red,
|
||||||
|
),onPressed: (){}, child: Row(
|
||||||
|
children: [
|
||||||
|
FaIcon(FontAwesomeIcons.deleteLeft),
|
||||||
|
SizedBox(width: 10,),
|
||||||
|
Text('Delete'),
|
||||||
|
],
|
||||||
|
))
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
))
|
||||||
|
],
|
||||||
|
),
|
||||||
|
) ,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
List<Widget> printSteps() {
|
||||||
|
List<Widget> _steps = [];
|
||||||
|
|
||||||
|
Widget title=Container(
|
||||||
|
|
||||||
|
height: 30,
|
||||||
|
decoration: BoxDecoration(borderRadius: BorderRadius.circular(20), color: Colors.white10),
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 0),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Expanded(flex: 4, child: Text('Name')),
|
||||||
|
// Expanded(flex:1,child: Icon(Icons.timelapse)),
|
||||||
|
Expanded(flex: 2, child: Text("Progress")),
|
||||||
|
Expanded(
|
||||||
|
flex: 3,
|
||||||
|
child: Text('ETA',textAlign: TextAlign.end,))
|
||||||
|
],
|
||||||
|
));
|
||||||
|
|
||||||
|
// _steps.add(title);
|
||||||
|
// _steps.add(Divider());
|
||||||
|
for (int i = 0; i < steps.length; i++) {
|
||||||
|
ProjectStep value = steps[i];
|
||||||
|
_steps.add(InkWell(
|
||||||
|
child: Container(
|
||||||
|
height: 30,
|
||||||
|
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5), color:Colors.black26),
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 2),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Expanded(flex: 4, child: Text(value.stepName)),
|
||||||
|
// Expanded(flex:1,child: Icon(Icons.timelapse)),
|
||||||
|
Expanded(flex: 1, child: Text("${value.progress}%")),
|
||||||
|
Expanded(
|
||||||
|
flex: 3,
|
||||||
|
child: Text(
|
||||||
|
value.eta.toString() + " Hours",
|
||||||
|
textAlign: TextAlign.end,
|
||||||
|
))
|
||||||
|
],
|
||||||
|
))));
|
||||||
|
}
|
||||||
|
|
||||||
|
return _steps;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,11 @@
|
|||||||
|
import 'dart:ui';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:tasktracker/Data.dart';
|
import 'package:tasktracker/Data.dart';
|
||||||
import 'package:tasktracker/NewProject.dart';
|
import 'package:tasktracker/NewProject.dart';
|
||||||
|
import 'package:tasktracker/ProjectDetails.dart';
|
||||||
import 'Dialogs.dart';
|
import 'Dialogs.dart';
|
||||||
import 'User.dart' as User;
|
import 'User.dart' as User;
|
||||||
import 'main.dart';
|
import 'main.dart';
|
||||||
@@ -53,6 +56,7 @@ class _ProjectsState extends State<Projects> {
|
|||||||
BottomNavigationBarItem(icon: FaIcon(FontAwesomeIcons.newspaper),label:'Summary'),
|
BottomNavigationBarItem(icon: FaIcon(FontAwesomeIcons.newspaper),label:'Summary'),
|
||||||
BottomNavigationBarItem(icon: FaIcon(FontAwesomeIcons.info),label:'Details'),
|
BottomNavigationBarItem(icon: FaIcon(FontAwesomeIcons.info),label:'Details'),
|
||||||
],
|
],
|
||||||
|
currentIndex:selectedPage,
|
||||||
onTap: (val){
|
onTap: (val){
|
||||||
selectedPage= val;
|
selectedPage= val;
|
||||||
setState(() {
|
setState(() {
|
||||||
@@ -94,13 +98,97 @@ class _ProjectsState extends State<Projects> {
|
|||||||
],
|
],
|
||||||
)),
|
)),
|
||||||
drawer: navDrawer(context, 7),
|
drawer: navDrawer(context, 7),
|
||||||
body: (selectedPage == 0) ?
|
body:
|
||||||
Container(child: Column(
|
(User.projects.isEmpty)? Container(child: Image.asset(('images/project.png'),color: Colors.white.withOpacity(0.6), colorBlendMode: BlendMode.modulate,)) :
|
||||||
|
(selectedPage == 0) ?
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.all(15),
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
|
Card(child:
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
FaIcon(FontAwesomeIcons.cogs, color: Colors.yellow),
|
||||||
|
SizedBox(width: 15,),
|
||||||
|
Text('Active Projects (${User.projects.length})',style:TextStyle(fontSize: 18)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Divider(),
|
||||||
|
Container(
|
||||||
|
height: 100,
|
||||||
|
child: ListView.builder(
|
||||||
|
itemCount: User.projects.length,
|
||||||
|
itemBuilder: (context,index){
|
||||||
|
return InkWell(
|
||||||
|
onTap: (){
|
||||||
|
Navigator.of(context).push(MaterialPageRoute(builder: (context)=> ProjectDetails()));
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(color: Colors.black26, borderRadius: BorderRadius.circular(10)),
|
||||||
|
padding:EdgeInsets.all(8),
|
||||||
|
margin: EdgeInsets.all(1),
|
||||||
|
child:
|
||||||
|
Row(mainAxisSize: MainAxisSize.max,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Expanded(flex:3,child: Text(User.projects[index].name)),
|
||||||
|
Expanded(flex:2,child: Text('20% [200h]')),
|
||||||
|
Expanded(
|
||||||
|
flex:2,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
color: User.projects[index].cat!.productive ? Colors.green : Colors.redAccent,
|
||||||
|
),
|
||||||
|
padding:EdgeInsets.symmetric(horizontal: 8),
|
||||||
|
child:Text(User.projects[index].cat!.name)
|
||||||
|
)
|
||||||
|
],),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
],
|
],
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
SizedBox(height: 30,),
|
||||||
|
Card(child:
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
FaIcon(FontAwesomeIcons.check,color: Colors.green,),
|
||||||
|
SizedBox(width: 15,),
|
||||||
|
Text('Finished Projects (0)',style:TextStyle(fontSize: 18)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Divider(),
|
||||||
|
Container(
|
||||||
|
height: 50,
|
||||||
|
)
|
||||||
|
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
],
|
||||||
))
|
))
|
||||||
:Container(
|
:
|
||||||
|
Container(
|
||||||
padding: EdgeInsets.all(10),
|
padding: EdgeInsets.all(10),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
|
|||||||
@@ -167,6 +167,7 @@ class _TasksState extends State<Tasks> {
|
|||||||
children: [
|
children: [
|
||||||
(relatedProjects.isNotEmpty)
|
(relatedProjects.isNotEmpty)
|
||||||
? Container(
|
? Container(
|
||||||
|
margin: EdgeInsets.symmetric(horizontal: 5),
|
||||||
padding: EdgeInsets.symmetric(horizontal: 10),
|
padding: EdgeInsets.symmetric(horizontal: 10),
|
||||||
decoration:
|
decoration:
|
||||||
BoxDecoration(borderRadius: BorderRadius.circular(10), color: Colors.black26),
|
BoxDecoration(borderRadius: BorderRadius.circular(10), color: Colors.black26),
|
||||||
@@ -185,6 +186,18 @@ class _TasksState extends State<Tasks> {
|
|||||||
Container(margin: EdgeInsets.fromLTRB(15, 0, 15, 10), height: 2, color: color)
|
Container(margin: EdgeInsets.fromLTRB(15, 0, 15, 10), height: 2, color: color)
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
|
(selecting)
|
||||||
|
? InkWell(
|
||||||
|
child:Container(margin:EdgeInsets.all(8),child: Icon(Icons.edit)),
|
||||||
|
onTap: () {
|
||||||
|
print('edit $name : $catName : $relatedProjects');
|
||||||
|
|
||||||
|
Navigator.of(context).push(MaterialPageRoute(builder: (context)=> NewTask(t_name: name, t_cat: catName, t_relProj: (relatedProjects.isEmpty)? null : relatedProjects,))).then((value){setState(() {
|
||||||
|
|
||||||
|
});});
|
||||||
|
|
||||||
|
})
|
||||||
|
: Container(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -898,6 +898,43 @@ class UserOperations {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Future<void> editTaskType(String oldName, String name, String category, {bool bulk = false, String? relatedProject = null}) async {
|
||||||
|
Map<String, String> queryBody = <String, String>{
|
||||||
|
'id': username + oldName,
|
||||||
|
'username': username,
|
||||||
|
'name': name,
|
||||||
|
'category': username + category,
|
||||||
|
'related_project' :(relatedProject==null) ? '' : (username + relatedProject)
|
||||||
|
};
|
||||||
|
|
||||||
|
if (cacheEnabled) {
|
||||||
|
//Add Query
|
||||||
|
Map<String, Object> query = {Queries.colLink: 'edit_taskType', Queries.colData: jsonEncode(queryBody)};
|
||||||
|
|
||||||
|
print("adding new query ${query[Queries.colLink]} : ${jsonEncode(queryBody)}");
|
||||||
|
|
||||||
|
await cacheDb.insert('Queries', query);
|
||||||
|
|
||||||
|
//update Cache
|
||||||
|
await cacheDb.rawUpdate("UPDATE TaskTypes SET ${TaskType.colId}='${username+name}', ${TaskType.colName}='$name', ${TaskType.colCategory}='${username+category}', ${TaskType.colRelatedProject}='${(relatedProject == 'None') ? '' : relatedProject}' WHERE id='${username+oldName}'");
|
||||||
|
await refreshUserData(forceOffline: true);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
http.Response queryResponse = (await http.post(Uri.parse('http://161.97.127.136/task_tracker/add_taskType.php'), body: queryBody));
|
||||||
|
print("Query executed : Results{${queryResponse.body}");
|
||||||
|
if (queryResponse.body.toLowerCase().contains("success")) {
|
||||||
|
//Success
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
print('NC: Error editing task $e}');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!bulk) {
|
||||||
|
//Add to server and refresh Cache
|
||||||
|
await executeQueries();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static Future<void> addActivity(String type, DateTime sTime, DateTime eTime,
|
static Future<void> addActivity(String type, DateTime sTime, DateTime eTime,
|
||||||
{String metadata = 'null', bool bulk = false, Function(int)? onOverlap}) async {
|
{String metadata = 'null', bool bulk = false, Function(int)? onOverlap}) async {
|
||||||
Map<String, String> queryBody = <String, String>{
|
Map<String, String> queryBody = <String, String>{
|
||||||
@@ -1098,7 +1135,7 @@ class UserOperations {
|
|||||||
print('NC: Error adding prjct $e}');
|
print('NC: Error adding prjct $e}');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
UserOperations.addTaskType(name, category, relatedProject: name);
|
||||||
await executeQueries();
|
await executeQueries();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -208,14 +208,23 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||||||
hourglassStops = [];
|
hourglassStops = [];
|
||||||
hourglassTotalTime=0;
|
hourglassTotalTime=0;
|
||||||
hourglassCatData.forEach((element) {
|
hourglassCatData.forEach((element) {
|
||||||
if(element.time > hourglassTotalTime){
|
// if(element.time > hourglassTotalTime){
|
||||||
hourglassTotalTime=element.time;
|
hourglassTotalTime+=element.time;
|
||||||
}
|
// }
|
||||||
});
|
});
|
||||||
hourglassCatData.forEach((element) {
|
print('hourglass cat data');
|
||||||
|
double stopsTotal = 0;
|
||||||
|
for(int i =0 ; i < hourglassCatData.length; i++) {
|
||||||
|
CatMapData element = hourglassCatData[i];
|
||||||
|
print('${element.name} : ${element.time} / $hourglassTotalTime = ${element.time / hourglassTotalTime}');
|
||||||
|
double thisStop = ( element.time/hourglassTotalTime);
|
||||||
hourglassColors.add(element.color);
|
hourglassColors.add(element.color);
|
||||||
hourglassStops.add(element.time/hourglassTotalTime);
|
hourglassStops.add(stopsTotal+thisStop);
|
||||||
});
|
stopsTotal += thisStop;
|
||||||
|
if(i < hourglassCatData.length-1){hourglassColors.add(hourglassCatData[i+1].color);
|
||||||
|
hourglassStops.add(stopsTotal+thisStop + 0.001);}
|
||||||
|
}
|
||||||
|
print('total Stops ${stopsTotal}');
|
||||||
print('maxT: $hourglassTotalTime');
|
print('maxT: $hourglassTotalTime');
|
||||||
if(hourglassColors.isEmpty){
|
if(hourglassColors.isEmpty){
|
||||||
hourglassColors.add(Colors.black);
|
hourglassColors.add(Colors.black);
|
||||||
@@ -272,15 +281,23 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||||||
ongoingActName = "";
|
ongoingActName = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(mounted) {
|
||||||
setState(() {
|
setState(() {
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
bool loadingStats = false;
|
||||||
void LoadStats() async {
|
void LoadStats() async {
|
||||||
// return;
|
// return;
|
||||||
// await User.refreshUserData();
|
// await User.refreshUserData();
|
||||||
|
|
||||||
|
if(loadingStats){
|
||||||
|
print('loading stats already');
|
||||||
|
return;
|
||||||
|
}else {
|
||||||
|
loadingStats=true;
|
||||||
|
}
|
||||||
await Refresh();
|
await Refresh();
|
||||||
|
|
||||||
DateFormat dFormat = DateFormat("MM/dd");
|
DateFormat dFormat = DateFormat("MM/dd");
|
||||||
@@ -434,8 +451,9 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||||||
int prodActs = (productivtyActs[element] ?? 0);
|
int prodActs = (productivtyActs[element] ?? 0);
|
||||||
int unprodActs = (unproductivtyActs[element] ?? 0);
|
int unprodActs = (unproductivtyActs[element] ?? 0);
|
||||||
double prod = (untrackedUnprod) ? ((prodActs / 1440) * 100) : ((prodActs / unprodActs)*100);
|
double prod = (untrackedUnprod) ? ((prodActs / 1440) * 100) : ((prodActs / unprodActs)*100);
|
||||||
if(prod>0){
|
var newProdData = ProductivityMapData(element, prod);
|
||||||
productivityData.add(ProductivityMapData(element, prod));
|
if(prod>0 && !productivityData.contains(newProdData)){
|
||||||
|
productivityData.add(newProdData);
|
||||||
}
|
}
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
@@ -462,7 +480,11 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
print('prodData : $productivityData');
|
// print('productivity data');
|
||||||
|
// productivityData.forEach((element) {
|
||||||
|
// print(element.day);
|
||||||
|
// });
|
||||||
|
loadingStats=false;
|
||||||
// loadingStats=false;
|
// loadingStats=false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,7 +58,8 @@ class _NewActivity extends State<NewActivity> {
|
|||||||
if(_cats.contains(element.name)){
|
if(_cats.contains(element.name)){
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
_cats.add(name);}
|
_cats.add(name + ((element.relatedProject !=null) ? ' [${element.relatedProject!.name}]' :''));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return _cats;
|
return _cats;
|
||||||
}
|
}
|
||||||
@@ -112,7 +113,9 @@ class _NewActivity extends State<NewActivity> {
|
|||||||
|
|
||||||
});});
|
});});
|
||||||
}else{
|
}else{
|
||||||
|
|
||||||
selectedCat = _value ?? 'n/a';
|
selectedCat = _value ?? 'n/a';
|
||||||
|
|
||||||
}
|
}
|
||||||
setState(() {
|
setState(() {
|
||||||
});
|
});
|
||||||
@@ -398,9 +401,14 @@ class _NewActivity extends State<NewActivity> {
|
|||||||
if(startTime.isAfter(endTime)){
|
if(startTime.isAfter(endTime)){
|
||||||
showAlertDialog(context, 'Really?', 'Start time and end time doesnt make any sense');
|
showAlertDialog(context, 'Really?', 'Start time and end time doesnt make any sense');
|
||||||
}
|
}
|
||||||
print('adding Task Type : $selectedCat at $startTime - $endTime');
|
String selectedTasks = selectedCat;
|
||||||
|
if(selectedTasks.contains('[') && selectedTasks.contains(']')){
|
||||||
|
selectedTasks = selectedTasks.substring(0, selectedTasks.indexOf('[')-1);
|
||||||
|
print('Project task : $selectedTasks');
|
||||||
|
}
|
||||||
|
print('adding Task Type : $selectedTasks at $startTime - $endTime');
|
||||||
bool failed=false;
|
bool failed=false;
|
||||||
await User.UserOperations.addActivity(selectedCat,startTime, endTime,metadata:metadataController.text, onOverlap: (overlapCount){
|
await User.UserOperations.addActivity(selectedTasks,startTime, endTime,metadata:metadataController.text, onOverlap: (overlapCount){
|
||||||
showAlertDialog(context, 'Error adding activity', 'Cannot add activity between ${dateFormat.format(startTime)} - ${dateFormat.format(endTime)}, $overlapCount activities are already added within this time range');
|
showAlertDialog(context, 'Error adding activity', 'Cannot add activity between ${dateFormat.format(startTime)} - ${dateFormat.format(endTime)}, $overlapCount activities are already added within this time range');
|
||||||
failed=true;
|
failed=true;
|
||||||
});
|
});
|
||||||
@@ -416,9 +424,14 @@ class _NewActivity extends State<NewActivity> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void edit_action() async{
|
void edit_action() async{
|
||||||
print('adding Task Type : $selectedCat at $startTime - $endTime');
|
String selectedTasks = selectedCat;
|
||||||
|
if(selectedTasks.contains('[') && selectedTasks.contains(']')){
|
||||||
|
selectedTasks = selectedTasks.substring(0, selectedTasks.indexOf('[')-1);
|
||||||
|
print('Project task : $selectedTasks');
|
||||||
|
}
|
||||||
|
print('adding Task Type : $selectedTasks at $startTime - $endTime');
|
||||||
bool failed=false;
|
bool failed=false;
|
||||||
await User.UserOperations.editActivity(init_sTime,init_eTime,selectedCat,startTime, endTime,metadata:metadataController.text, onOverlap: (overlapCount){
|
await User.UserOperations.editActivity(init_sTime,init_eTime,selectedTasks,startTime, endTime,metadata:metadataController.text, onOverlap: (overlapCount){
|
||||||
showAlertDialog(context, 'Error editing activity', 'Cannot add activity between ${dateFormat.format(startTime)} - ${dateFormat.format(endTime)}, $overlapCount activities are already added within this time range');
|
showAlertDialog(context, 'Error editing activity', 'Cannot add activity between ${dateFormat.format(startTime)} - ${dateFormat.format(endTime)}, $overlapCount activities are already added within this time range');
|
||||||
failed=true;
|
failed=true;
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user