mirror of
https://bitbucket.org/FransoletThomas/tablet-app.git
synced 2025-12-06 16:41:19 +00:00
WIP geopoints filter
This commit is contained in:
parent
59618c84e0
commit
fbf051b23f
168
lib/Screens/Map/geo_point_filter.dart
Normal file
168
lib/Screens/Map/geo_point_filter.dart
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
import 'dart:ui';
|
||||||
|
|
||||||
|
//import 'package:animated_tree_view/animated_tree_view.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_widget_from_html/flutter_widget_from_html.dart';
|
||||||
|
import 'package:generate_tree/generate_tree.dart';
|
||||||
|
import 'package:generate_tree/treeNode.dart';
|
||||||
|
import 'package:manager_api/api.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:tablet_app/Models/tabletContext.dart';
|
||||||
|
import 'package:tablet_app/app_context.dart';
|
||||||
|
import 'package:tablet_app/constants.dart';
|
||||||
|
import 'package:html/parser.dart' show parse;
|
||||||
|
|
||||||
|
class GeoPointFilter extends StatefulWidget {
|
||||||
|
final String language;
|
||||||
|
final List<GeoPointDTO> geoPoints;
|
||||||
|
final List<CategorieDTO> categories;
|
||||||
|
final Function(List<GeoPointDTO>?) filteredPoints;
|
||||||
|
|
||||||
|
GeoPointFilter({required this.language, required this.geoPoints, required this.categories, required this.filteredPoints});
|
||||||
|
|
||||||
|
@override
|
||||||
|
_GeoPointFilterState createState() => _GeoPointFilterState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _GeoPointFilterState extends State<GeoPointFilter> {
|
||||||
|
List<GeoPointDTO> selectedGeoPoints = [];
|
||||||
|
//late List<TreeNode> treeNodes;
|
||||||
|
late List<TreeNode> _filteredNodes;
|
||||||
|
late ValueNotifier<String> _searchTextNotifier;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_searchTextNotifier = ValueNotifier<String>('');
|
||||||
|
//_searchTextNotifier.addListener(_onSearchTextChanged); // Cause the setState ?
|
||||||
|
// Construire les nœuds de l'arborescence en utilisant les catégories et les géopoints
|
||||||
|
//treeNodes = buildTreeNodes(widget.categories, widget.geoPoints);
|
||||||
|
_filteredNodes = buildTreeNodes(widget.categories, widget.geoPoints);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onSearchTextChanged() {
|
||||||
|
filterNodes(_searchTextNotifier.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<TreeNode> buildTreeNodes(List<CategorieDTO> categories, List<GeoPointDTO> geoPoints) {
|
||||||
|
List<TreeNode> nodes = [];
|
||||||
|
|
||||||
|
// Pour chaque catégorie, créez un nœud parent
|
||||||
|
for (var category in categories) {
|
||||||
|
TreeNode categoryNode = TreeNode(
|
||||||
|
id: category.id ?? 0,
|
||||||
|
title: parse(category.label!.firstWhere((l) => l.language == widget.language).value!).documentElement!.text,
|
||||||
|
children: [],
|
||||||
|
checked: false,
|
||||||
|
show: false,
|
||||||
|
pid: 0,
|
||||||
|
commonID: 0,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Ajoutez les géopoints correspondant à cette catégorie en tant qu'enfants du nœud parent
|
||||||
|
for (var geoPoint in geoPoints) {
|
||||||
|
if (geoPoint.categorieId == category.id) {
|
||||||
|
TreeNode geoPointNode = TreeNode(
|
||||||
|
id: geoPoint.id ?? 0,
|
||||||
|
title: parse(geoPoint.title!.firstWhere((l) => l.language == widget.language).value!).documentElement!.text,
|
||||||
|
checked: false,
|
||||||
|
show: false,
|
||||||
|
children: [],
|
||||||
|
pid: 0,
|
||||||
|
commonID: 0,
|
||||||
|
);
|
||||||
|
categoryNode.children.add(geoPointNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nodes.add(categoryNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
void filterNodes(String searchText) {
|
||||||
|
//setState(() {
|
||||||
|
_searchTextNotifier.value = searchText;
|
||||||
|
//_searchText = searchText;
|
||||||
|
// Filtrer les nœuds en fonction du texte de recherche
|
||||||
|
_filteredNodes = _searchTextNotifier.value.isEmpty
|
||||||
|
? buildTreeNodes(widget.categories, widget.geoPoints)
|
||||||
|
: _filterNodesBySearchText(_searchTextNotifier.value);
|
||||||
|
//});
|
||||||
|
}
|
||||||
|
|
||||||
|
List<TreeNode> _filterNodesBySearchText(String searchText) {
|
||||||
|
List<TreeNode> filteredNodes = [];
|
||||||
|
for (var node in buildTreeNodes(widget.categories, widget.geoPoints)) {
|
||||||
|
if (node.title.toLowerCase().contains(searchText.toLowerCase())) {
|
||||||
|
// Si le titre du nœud contient le texte de recherche, ajoutez-le aux nœuds filtrés
|
||||||
|
filteredNodes.add(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return filteredNodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
Size size = MediaQuery.of(context).size;
|
||||||
|
final appContext = Provider.of<AppContext>(context);
|
||||||
|
TabletAppContext tabletAppContext = appContext.getContext();
|
||||||
|
var currentLanguage = tabletAppContext.language;
|
||||||
|
|
||||||
|
var primaryColor = tabletAppContext.configuration != null ? tabletAppContext.configuration!.primaryColor != null ? new Color(int.parse(tabletAppContext.configuration!.primaryColor!.split('(0x')[1].split(')')[0], radix: 16)) : kTestSecondColor : kTestSecondColor;
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: kBackgroundColor.withOpacity(0.78),
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0)),
|
||||||
|
),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
TextFormField(
|
||||||
|
//initialValue: 'Input text',
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: 'Recherche',
|
||||||
|
suffixIcon: Icon(
|
||||||
|
Icons.search,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
onChanged: filterNodes,
|
||||||
|
),
|
||||||
|
ValueListenableBuilder<String>(
|
||||||
|
valueListenable: _searchTextNotifier,
|
||||||
|
builder: (context, value, _) {
|
||||||
|
return Container(
|
||||||
|
color: Colors.greenAccent,
|
||||||
|
height: size.height * 0.7,
|
||||||
|
width: size.width * 0.3,
|
||||||
|
child: GenerateTree(
|
||||||
|
data: _filteredNodes,
|
||||||
|
selectOneToAll: true,
|
||||||
|
textColor: Colors.black,
|
||||||
|
onChecked: (node, checked, commonID) {
|
||||||
|
if(checked) {
|
||||||
|
//node.
|
||||||
|
//var test =
|
||||||
|
//selectedGeoPoints.add();
|
||||||
|
}
|
||||||
|
print('isChecked : $checked');
|
||||||
|
print('common Node ID : ${commonID}');
|
||||||
|
print('children node data : ${node.children.map((e) => '${e.title}')}');
|
||||||
|
// Todo update selection
|
||||||
|
},
|
||||||
|
checkBoxColor: primaryColor,
|
||||||
|
childrenPadding: EdgeInsets.only(left: 20, top: 10, right: 0, bottom: 10),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -9,9 +9,12 @@ import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart' as mapBox;
|
|||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:tablet_app/Components/multi_select_container.dart';
|
import 'package:tablet_app/Components/multi_select_container.dart';
|
||||||
import 'package:tablet_app/Models/map-marker.dart';
|
import 'package:tablet_app/Models/map-marker.dart';
|
||||||
|
import 'package:tablet_app/Models/tabletContext.dart';
|
||||||
|
import 'package:tablet_app/Screens/Map/geo_point_filter.dart';
|
||||||
import 'package:tablet_app/Screens/Map/map_context.dart';
|
import 'package:tablet_app/Screens/Map/map_context.dart';
|
||||||
import 'package:html/parser.dart' show parse;
|
import 'package:html/parser.dart' show parse;
|
||||||
import 'package:tablet_app/Screens/Map/map_view.dart';
|
import 'package:tablet_app/Screens/Map/map_view.dart';
|
||||||
|
import 'package:tablet_app/app_context.dart';
|
||||||
import 'package:tablet_app/constants.dart';
|
import 'package:tablet_app/constants.dart';
|
||||||
|
|
||||||
class MapBoxView extends StatefulWidget {
|
class MapBoxView extends StatefulWidget {
|
||||||
@ -53,6 +56,7 @@ class AnnotationClickListener extends mapBox.OnPointAnnotationClickListener {
|
|||||||
class _MapBoxViewState extends State<MapBoxView> {
|
class _MapBoxViewState extends State<MapBoxView> {
|
||||||
late mapBox.MapboxMap? mapboxMap;
|
late mapBox.MapboxMap? mapboxMap;
|
||||||
late mapBox.PointAnnotationManager? pointAnnotationManager;
|
late mapBox.PointAnnotationManager? pointAnnotationManager;
|
||||||
|
bool filterZoneSelected = false;
|
||||||
|
|
||||||
createPoints() {
|
createPoints() {
|
||||||
var options = <mapBox.PointAnnotationOptions>[];
|
var options = <mapBox.PointAnnotationOptions>[];
|
||||||
@ -126,6 +130,8 @@ class _MapBoxViewState extends State<MapBoxView> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final mapContext = Provider.of<MapContext>(context);
|
final mapContext = Provider.of<MapContext>(context);
|
||||||
|
final appContext = Provider.of<AppContext>(context);
|
||||||
|
TabletAppContext tabletAppContext = appContext.getContext() as TabletAppContext;
|
||||||
Size size = MediaQuery.of(context).size;
|
Size size = MediaQuery.of(context).size;
|
||||||
|
|
||||||
var type = mapBox.MapboxStyles.STANDARD;
|
var type = mapBox.MapboxStyles.STANDARD;
|
||||||
@ -173,31 +179,19 @@ class _MapBoxViewState extends State<MapBoxView> {
|
|||||||
)
|
)
|
||||||
),
|
),
|
||||||
Positioned(
|
Positioned(
|
||||||
bottom: 35,
|
left: 5,
|
||||||
left: 10,
|
top: 35,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: size.width * 0.85,
|
width: size.width * 0.3,
|
||||||
child: MultiSelectContainer(
|
height: size.height * 0.76,
|
||||||
label: null,
|
child: GeoPointFilter(
|
||||||
color: kBackgroundGrey,
|
language: tabletAppContext.language!,
|
||||||
initialValue: selectedCategories!,
|
geoPoints: widget.mapDTO!.points!,
|
||||||
isMultiple: true,
|
categories: widget.mapDTO!.categories!,
|
||||||
values: widget.mapDTO!.categories!.map((categorie) => categorie.label!.firstWhere((element) => element.language == widget.language).value!).toList(),
|
filteredPoints: (filteredPoints) {
|
||||||
onChanged: (value) {
|
print("COUCOU FILTERED POINTS");
|
||||||
var tempOutput = new List<String>.from(value);
|
print(filteredPoints);
|
||||||
print(tempOutput);
|
}),
|
||||||
if(init) {
|
|
||||||
setState(() {
|
|
||||||
selectedCategories = tempOutput;
|
|
||||||
pointsToShow = widget.mapDTO!.points!.where((point) => tempOutput.any((tps) => point.categorie?.label?.firstWhere((lab) => lab.language == widget.language).value == tps) || point.categorie == null).toList();
|
|
||||||
//markers = getMarkers(widget.language, mapContext);
|
|
||||||
pointAnnotationManager!.deleteAll();
|
|
||||||
pointAnnotationManager!.createMulti(createPoints());
|
|
||||||
mapContext.notifyListeners();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@ -33,6 +33,7 @@ class MenuView extends StatefulWidget {
|
|||||||
class _MenuView extends State<MenuView> {
|
class _MenuView extends State<MenuView> {
|
||||||
MenuDTO menuDTO = MenuDTO();
|
MenuDTO menuDTO = MenuDTO();
|
||||||
SectionDTO? selectedSection;
|
SectionDTO? selectedSection;
|
||||||
|
bool isImageBackground = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@ -40,6 +41,8 @@ class _MenuView extends State<MenuView> {
|
|||||||
menuDTO = MenuDTO.fromJson(jsonDecode(widget.section.data!))!;
|
menuDTO = MenuDTO.fromJson(jsonDecode(widget.section.data!))!;
|
||||||
print(menuDTO);
|
print(menuDTO);
|
||||||
|
|
||||||
|
isImageBackground = true; //widget.isImageBackground;
|
||||||
|
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,10 +180,10 @@ class _MenuView extends State<MenuView> {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: boxDecoration(appContext, menuDTO.sections![index], false),
|
decoration: isImageBackground ? boxDecoration(appContext, menuDTO.sections![index], false) : null,
|
||||||
padding: const EdgeInsets.all(25),
|
padding: const EdgeInsets.all(25),
|
||||||
margin: EdgeInsets.symmetric(vertical: 15, horizontal: 15),
|
margin: EdgeInsets.symmetric(vertical: 15, horizontal: 15),
|
||||||
child: Align(
|
child: isImageBackground ? Align(
|
||||||
alignment: Alignment.bottomRight,
|
alignment: Alignment.bottomRight,
|
||||||
child: FractionallySizedBox(
|
child: FractionallySizedBox(
|
||||||
heightFactor: 0.5,
|
heightFactor: 0.5,
|
||||||
@ -209,6 +212,34 @@ class _MenuView extends State<MenuView> {
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
) : Column(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
flex: 8,
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: menuDTO.sections![index].imageSource == null ? kBackgroundColor : null, // default color if no image
|
||||||
|
shape: BoxShape.rectangle,
|
||||||
|
image: menuDTO.sections![index].imageSource != null ? new DecorationImage(
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
image: ImageCustomProvider.getImageProvider(appContext, menuDTO.sections![index].imageId!, menuDTO.sections![index].imageSource!),
|
||||||
|
): null,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
flex: 2,
|
||||||
|
child: Center(
|
||||||
|
child: HtmlWidget(
|
||||||
|
menuDTO.sections![index].title!.firstWhere((translation) => translation.language == appContext.getContext().language).value ?? "",
|
||||||
|
customStylesBuilder: (element) {
|
||||||
|
return {'text-align': 'center', 'font-family': "Roboto"};
|
||||||
|
},
|
||||||
|
textStyle: TextStyle(fontSize: 25),//calculateFontSize(constraints.maxWidth, constraints.maxHeight, kIsWeb ? kWebMenuTitleDetailSize : kMenuTitleDetailSize)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -234,7 +265,7 @@ boxDecoration(AppContext appContext, SectionDTO section, bool isSelected) {
|
|||||||
boxShadow: [
|
boxShadow: [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: kBackgroundSecondGrey,
|
color: kBackgroundSecondGrey,
|
||||||
spreadRadius: 0.5,
|
spreadRadius: 0.3,
|
||||||
blurRadius: 5,
|
blurRadius: 5,
|
||||||
offset: Offset(0, 1.5), // changes position of shadow
|
offset: Offset(0, 1.5), // changes position of shadow
|
||||||
),
|
),
|
||||||
|
|||||||
@ -65,6 +65,8 @@ dependencies:
|
|||||||
path_provider: ^2.1.2
|
path_provider: ^2.1.2
|
||||||
permission_handler: ^11.2.0
|
permission_handler: ^11.2.0
|
||||||
google_fonts: ^6.2.1
|
google_fonts: ^6.2.1
|
||||||
|
#animated_tree_view: ^2.2.0
|
||||||
|
generate_tree: ^2.2.2
|
||||||
|
|
||||||
openapi_generator_cli: ^4.13.1
|
openapi_generator_cli: ^4.13.1
|
||||||
openapi_generator: ^4.13.1
|
openapi_generator: ^4.13.1
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user