add flow notes
This commit is contained in:
parent
097e6a6de5
commit
20bc5a9ae6
4 changed files with 190 additions and 72 deletions
26
lib/api.dart
26
lib/api.dart
|
@ -289,6 +289,18 @@ class API {
|
|||
var resp = jsonDecode(await getRequest("$instance/location/$id"));
|
||||
return Location(resp);
|
||||
}
|
||||
|
||||
Future<String> addNoteToFlow(String flowID, String content) async {
|
||||
var res = jsonDecode(
|
||||
await postRequest("$instance/flow/$flowID/note", {"content": content}));
|
||||
return res["uuid"];
|
||||
}
|
||||
|
||||
Future<List<FlowNote>> getNotesOfFlow(String flowID) async {
|
||||
var resp = jsonDecode(await getRequest("$instance/flow/$flowID/notes"))
|
||||
as List<dynamic>;
|
||||
return resp.map((x) => FlowNote(x)).toList();
|
||||
}
|
||||
}
|
||||
|
||||
class FlowInfo {
|
||||
|
@ -483,6 +495,20 @@ class FlowDone {
|
|||
}
|
||||
}
|
||||
|
||||
class FlowNote {
|
||||
late String uuid;
|
||||
late int timestamp;
|
||||
late String content;
|
||||
late String onFlow;
|
||||
|
||||
FlowNote(Map<String, dynamic> json) {
|
||||
uuid = json["uuid"];
|
||||
timestamp = json["timestamp"];
|
||||
content = json["content"];
|
||||
onFlow = json["on_flow"];
|
||||
}
|
||||
}
|
||||
|
||||
class GlobalItemStat {
|
||||
late int item_count;
|
||||
late int total_transactions;
|
||||
|
|
|
@ -1,92 +1,127 @@
|
|||
import 'package:cdb_ui/api.dart' as API;
|
||||
import 'package:cdb_ui/pages/flow/create_flow_page.dart';
|
||||
import 'package:cdb_ui/pages/flow/end_flow_page.dart';
|
||||
import 'package:cdb_ui/pages/flow/flow_note.dart';
|
||||
import 'package:cdb_ui/pages/transaction.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class ActiveFlowPage extends StatelessWidget {
|
||||
class ActiveFlowPage extends StatefulWidget {
|
||||
final API.Flow flow;
|
||||
final API.FlowInfo info;
|
||||
|
||||
const ActiveFlowPage(this.flow, this.info, {super.key});
|
||||
|
||||
@override
|
||||
State<ActiveFlowPage> createState() => _ActiveFlowPageState();
|
||||
}
|
||||
|
||||
class _ActiveFlowPageState extends State<ActiveFlowPage> {
|
||||
_refresh() {
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(info.name),
|
||||
actions: [
|
||||
appBar: AppBar(
|
||||
title: Text(widget.info.name),
|
||||
actions: [
|
||||
IconButton(
|
||||
onPressed: () async {
|
||||
if (widget.info.produces?.isNotEmpty ?? false) {
|
||||
Navigator.of(context).push(MaterialPageRoute(
|
||||
builder: (context) =>
|
||||
EndFlowWithProduce(widget.flow, widget.info)));
|
||||
return;
|
||||
}
|
||||
|
||||
// simple dialog
|
||||
var confirm = await showDialog(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
title: const Text('Are you sure?'),
|
||||
content: const Text('This will end the flow.'),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(context).pop(false),
|
||||
child: const Text('Cancel'),
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: () => Navigator.of(context).pop(true),
|
||||
child: const Text('End'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
if (confirm) {
|
||||
await API
|
||||
.API()
|
||||
.endFlow(widget.flow.id)
|
||||
.then((x) => Navigator.of(context).pop());
|
||||
}
|
||||
},
|
||||
icon: const Icon(Icons.stop)),
|
||||
// todo : continue next flow
|
||||
if (widget.info.next != null)
|
||||
IconButton(
|
||||
onPressed: () async {
|
||||
if (info.produces?.isNotEmpty ?? false) {
|
||||
onPressed: () {
|
||||
API.API().getFlowInfo(widget.info.next!).then((newInfo) {
|
||||
Navigator.of(context).push(MaterialPageRoute(
|
||||
builder: (context) => EndFlowWithProduce(flow, info)));
|
||||
return;
|
||||
}
|
||||
|
||||
// simple dialog
|
||||
var confirm = await showDialog(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
title: const Text('Are you sure?'),
|
||||
content: const Text('This will end the flow.'),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(context).pop(false),
|
||||
child: const Text('Cancel'),
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: () => Navigator.of(context).pop(true),
|
||||
child: const Text('End'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
if (confirm) {
|
||||
await API
|
||||
.API()
|
||||
.endFlow(flow.id)
|
||||
.then((x) => Navigator.of(context).pop());
|
||||
}
|
||||
builder: (context) {
|
||||
return CreateFlowPage(
|
||||
newInfo,
|
||||
() {},
|
||||
previousFlow: widget.flow,
|
||||
);
|
||||
},
|
||||
));
|
||||
});
|
||||
},
|
||||
icon: const Icon(Icons.stop)),
|
||||
// todo : continue next flow
|
||||
if (info.next != null)
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
API.API().getFlowInfo(info.next!).then((newInfo) {
|
||||
Navigator.of(context).push(MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return CreateFlowPage(
|
||||
newInfo,
|
||||
() {},
|
||||
previousFlow: flow,
|
||||
);
|
||||
},
|
||||
));
|
||||
});
|
||||
},
|
||||
icon: const Icon(Icons.arrow_forward)),
|
||||
|
||||
// todo : add notes to flow
|
||||
IconButton(onPressed: () {}, icon: const Icon(Icons.note))
|
||||
icon: const Icon(Icons.arrow_forward)),
|
||||
],
|
||||
),
|
||||
body: Column(
|
||||
children: [
|
||||
Text("ID: ${widget.flow.id}"),
|
||||
Text("Started since: ${tsFormat(widget.flow.started)}"),
|
||||
...widget.flow.input!.map((x) => Text("Input: $x")).toList(),
|
||||
if (widget.flow.done != null) ...[
|
||||
Text("Ended: ${tsFormat(widget.flow.done!.ended)}"),
|
||||
if (widget.flow.done!.next != null)
|
||||
Text("Next: ${widget.flow.done!.next!}"),
|
||||
...widget.flow.done!.produced!
|
||||
.map((x) => Text("Produced: $x"))
|
||||
.toList(),
|
||||
],
|
||||
),
|
||||
body: Column(
|
||||
children: [
|
||||
Text("ID: ${flow.id}"),
|
||||
Text("Started since: ${tsFormat(flow.started)}"),
|
||||
...flow.input!.map((x) => Text("Input: $x")).toList(),
|
||||
if (flow.done != null) ...[
|
||||
Text("Ended: ${tsFormat(flow.done!.ended)}"),
|
||||
if (flow.done!.next != null) Text("Next: ${flow.done!.next!}"),
|
||||
...flow.done!.produced!.map((x) => Text("Produced: $x")).toList(),
|
||||
],
|
||||
const Divider(),
|
||||
FutureBuilder(
|
||||
future: API.API().getNotesOfFlow(widget.flow.id),
|
||||
builder: (context, snapshot) {
|
||||
if (!snapshot.hasData) {
|
||||
return const CircularProgressIndicator();
|
||||
}
|
||||
|
||||
const Divider(),
|
||||
// todo : show notes
|
||||
],
|
||||
));
|
||||
var data = snapshot.data!;
|
||||
|
||||
return Expanded(
|
||||
child: ListView(
|
||||
children: data
|
||||
.map(
|
||||
(x) => FlowNoteCard(x),
|
||||
)
|
||||
.toList()));
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).push(MaterialPageRoute(
|
||||
builder: (context) => AddNotePage(widget.flow, _refresh)));
|
||||
},
|
||||
child: const Icon(Icons.note_add),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
57
lib/pages/flow/flow_note.dart
Normal file
57
lib/pages/flow/flow_note.dart
Normal file
|
@ -0,0 +1,57 @@
|
|||
import 'package:cdb_ui/pages/transaction.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cdb_ui/api.dart' as API;
|
||||
|
||||
class AddNotePage extends StatelessWidget {
|
||||
late final TextEditingController _noteController = TextEditingController();
|
||||
final API.Flow flow;
|
||||
final Function refresh;
|
||||
|
||||
AddNotePage(this.flow, this.refresh, {super.key});
|
||||
|
||||
_submit(BuildContext context) {
|
||||
API.API().addNoteToFlow(flow.id, _noteController.text).then((x) {
|
||||
refresh();
|
||||
Navigator.of(context).pop();
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text("Add Note"),
|
||||
),
|
||||
body: Column(
|
||||
children: [
|
||||
TextFormField(
|
||||
decoration: const InputDecoration(labelText: 'Note'),
|
||||
controller: _noteController,
|
||||
maxLines: 10),
|
||||
const SizedBox(
|
||||
height: 14,
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: _submit(context), child: const Text("Add Note"))
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class FlowNoteCard extends StatelessWidget {
|
||||
final API.FlowNote note;
|
||||
|
||||
const FlowNoteCard(this.note, {super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Card(
|
||||
child: ListTile(
|
||||
title: Text(tsFormat(note.timestamp),
|
||||
style: const TextStyle(fontSize: 12)),
|
||||
subtitle: Text(note.content, overflow: TextOverflow.ellipsis),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -179,8 +179,8 @@ class _SupplyPageState extends State<SupplyPage> {
|
|||
// Note
|
||||
TextFormField(
|
||||
decoration: const InputDecoration(labelText: 'Note'),
|
||||
keyboardType: TextInputType.number,
|
||||
controller: _noteController,
|
||||
maxLines: 5
|
||||
),
|
||||
|
||||
const SizedBox(height: 20),
|
||||
|
|
Loading…
Reference in a new issue