oc-search porting to flutter (missing compose + workflow editor)

This commit is contained in:
mr
2024-07-05 09:24:40 +02:00
parent a7f34db2e0
commit 7e4687853f
220 changed files with 10528 additions and 119 deletions

17
lib/widgets/catalog.dart Normal file
View File

@@ -0,0 +1,17 @@
import 'package:flutter/material.dart';
import 'package:oc_front/core/models/cart.dart';
import 'package:oc_front/models/search.dart';
import 'package:oc_front/widgets/items/item_row.dart';
class CatalogWidget extends StatefulWidget {
final List<AbstractItem>? items;
CatalogWidget ({ Key? key, this.items }): super(key: key);
@override CatalogWidgetState createState() => CatalogWidgetState();
}
class CatalogWidgetState extends State<CatalogWidget> {
@override Widget build(BuildContext context) {
var items = widget.items ?? WorkspaceLocal.items;
List<ItemRowWidget> itemRows = items.map((e) => ItemRowWidget(contextWidth: MediaQuery.of(context).size.width, item: e)).toList();
return SingleChildScrollView( child: Column( children: itemRows) );
}
}

View File

@@ -0,0 +1,40 @@
import 'package:flutter/material.dart';
import 'package:oc_front/models/search.dart';
import 'package:oc_front/widgets/items_details/data_item.dart';
class ItemWidget extends StatefulWidget {
AbstractItem item;
ItemWidget ({ super.key, required this.item });
@override ItemWidgetState createState() => ItemWidgetState();
}
class ItemWidgetState extends State<ItemWidget> {
@override Widget build(BuildContext context) {
Widget w = Container();
/* if (isData(widget.item.topic)) { w = DataItemWidget(item: widget.item as DataItem); }
else if (isComputing(widget.item.topic)) { w = DataItemWidget(item: widget.item as DataItem); }
else if (isDataCenter(widget.item.topic)) { w = DataItemWidget(item: widget.item as DataItem); }
else if (isStorage(widget.item.topic)) { w = DataItemWidget(item: widget.item as DataItem); } */
return Container(
height: MediaQuery.of(context).size.height - 300,
child: SingleChildScrollView(
child: Column( children: [
widget.item.description == null ? Container() : Container(
width: MediaQuery.of(context).size.width,
alignment: Alignment.center,
decoration: BoxDecoration(border: Border(bottom: BorderSide(color: Colors.grey.shade300))),
padding: const EdgeInsets.all(30),
child: Text(widget.item.description!,
style: TextStyle(fontSize: 15, color: Colors.grey, fontWeight: FontWeight.w500))),
Container(padding: const EdgeInsets.all(30),
color: Colors.grey.shade300,
width: MediaQuery.of(context).size.width / 2,
child: w
)
]
)
)
);
}
}

View File

@@ -0,0 +1,115 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:oc_front/models/search.dart';
import 'package:oc_front/core/models/cart.dart';
import 'package:oc_front/core/services/router.dart';
const List<GlobalKey<State>> _empty = [];
// ignore: must_be_immutable
class ItemRowWidget extends StatefulWidget {
bool readOnly = false;
double contextWidth = 0;
AbstractItem item;
List<GlobalKey<State>> keys = [];
ItemRowWidget ({ super.key,
required this.contextWidth, this.readOnly = false, required this.item, this.keys = _empty });
@override ItemRowWidgetState createState() => ItemRowWidgetState();
}
class ItemRowWidgetState extends State<ItemRowWidget> {
@override Widget build(BuildContext context) {
double imageSize = MediaQuery.of(context).size.width != widget.contextWidth ? 0 : 80;
var ratio = MediaQuery.of(context).size.width != widget.contextWidth ? 0.5 : 1; // 2;
var itemWidth = (((widget.contextWidth - imageSize) / 3) - 80) / ratio;
itemWidth = itemWidth > 100 ? 100 : ( itemWidth < 40 ? 40 : itemWidth );
var endWidth = (itemWidth * ratio) + 80;
Image? image;
if (widget.item.logo != null) {
image = Image.memory(base64Decode(widget.item.logo ?? ""), width: imageSize, height: imageSize);
}
Widget w = Container(
width: widget.contextWidth,
height: 100,
decoration: BoxDecoration( border: Border(bottom: BorderSide(color: Colors.grey.shade300)) ),
child: Row( children: [
Padding( padding: const EdgeInsets.all(10),
child: image ?? Image.network('https://get-picto.com/wp-content/uploads/2024/01/logo-instagram-png.webp',
height: imageSize, width: imageSize)),
Container(
width: widget.contextWidth - (imageSize + 20) - endWidth,
child: Padding(padding: widget.contextWidth != MediaQuery.of(context).size.width ?
const EdgeInsets.symmetric(horizontal: 10) : const EdgeInsets.symmetric(horizontal: 20),
child: Column(crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center, children: [
Row( children: [
Container(padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 10),
margin: const EdgeInsets.only(right: 20),
decoration: BoxDecoration(
color: isData(widget.item.topic) ? Colors.blue :
isComputing(widget.item.topic) ? Colors.green :
isDataCenter(widget.item.topic) ? Colors.orange :
isStorage(widget.item.topic) ? Colors.red : Colors.grey,
borderRadius: BorderRadius.circular(4),
),
child: Text( MediaQuery.of(context).size.width < 600 ? "" : widget.item.type.toString(),
style: const TextStyle(fontSize: 10, color: Colors.white, fontWeight: FontWeight.w600)),
),
Expanded( child: Text(widget.item.name?.toUpperCase() ?? "",
style: const TextStyle(fontSize: 20, overflow: TextOverflow.ellipsis, fontWeight: FontWeight.w600, color: Color(0xFFF67C0B9))),
)
]),
Text( "From ${widget.item.owner ?? "unknown owner"}",
style: TextStyle(fontSize: 14, color: Colors.grey, overflow: TextOverflow.ellipsis)),
Text(widget.item.shortDescription ?? "", style: const TextStyle(fontSize: 12, overflow: TextOverflow.ellipsis)),
],)
)
),
Container(
width: endWidth,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children : [
InkWell(
mouseCursor: SystemMouseCursors.click,
onTap: () {
setState(() {
if (WorkspaceLocal.hasItem(widget.item)) { WorkspaceLocal.removeItem(widget.item);
} else { WorkspaceLocal.addItem(widget.item); }
});
for (var key in widget.keys) { key.currentState?.setState(() {}); }
},
child: Container(
height: 40,
constraints: const BoxConstraints(maxWidth: 80),
width: itemWidth,
decoration: BoxDecoration(
boxShadow: [BoxShadow(color: Colors.grey.shade300, spreadRadius: 1, blurRadius: 1, offset: const Offset(0, 1))],
color: (WorkspaceLocal.hasItem(widget.item) ? Colors.red : const Color.fromRGBO(38, 166, 154, 1)),
borderRadius: BorderRadius.circular(4),
),
child: Icon(WorkspaceLocal.hasItem(widget.item) ? Icons.remove_shopping_cart : Icons.add_shopping_cart,
color: Colors.white, size: 20 ))
),
...(ratio > 1 ? [Padding( padding: const EdgeInsets.only(left: 20),
child: InkWell(
mouseCursor: SystemMouseCursors.click,
onTap: () { },
child: Container(
height: 40,
constraints: const BoxConstraints(maxWidth: 80, minWidth: 40),
width: itemWidth,
decoration: BoxDecoration(
boxShadow: [BoxShadow(color: Colors.grey.shade300, spreadRadius: 1, blurRadius: 1, offset: const Offset(0, 1))],
color: Colors.grey.shade300,
borderRadius: BorderRadius.circular(4),
),
child: const Icon(Icons.favorite_border, color: Colors.white, size: 20 ))
)
)] : [])
])
)]),
);
return widget.readOnly ? w : InkWell( mouseCursor: SystemMouseCursors.click,
onTap: () { AppRouter.zones.last.go(context, { "id" : widget.item.id ?? "" }); },
child: w );
}
}

View File

@@ -0,0 +1,27 @@
import 'package:flutter/material.dart';
import 'package:oc_front/models/search.dart';
class DataItemWidget extends StatefulWidget {
DataItem item;
DataItemWidget ({ super.key, required this.item });
@override DataItemWidgetState createState() => DataItemWidgetState();
}
class DataItemWidgetState extends State<DataItemWidget> {
@override Widget build(BuildContext context) {
return Wrap( children: [
Padding(padding: EdgeInsets.symmetric(vertical: 20, horizontal: 100),
child: Text("type : ${widget.item.dtype ?? "unknown type"}",
style: TextStyle(fontSize: 15, fontWeight: FontWeight.w600))),
Padding(padding: EdgeInsets.symmetric(horizontal: 100, vertical: 20),
child: Text("location : ${widget.item.location ?? "unknown location"}",
style: TextStyle(fontSize: 15, fontWeight: FontWeight.w600))),
Padding(padding: EdgeInsets.symmetric(horizontal: 100, vertical: 20),
child: Text("protocol : ${widget.item.protocol.isEmpty ? "no protocol founded" : widget.item.protocol.join(",")}",
style: TextStyle(fontSize: 15, fontWeight: FontWeight.w600))),
Padding(padding: EdgeInsets.symmetric(horizontal: 100, vertical: 20),
child: Text("ex : ${widget.item.example ?? "no example"}",
style: TextStyle(fontSize: 15, fontWeight: FontWeight.w600))),
]);
}
}