import 'package:diacritic/diacritic.dart'; import 'package:manager_app/l10n/app_localizations.dart'; import 'package:flutter/material.dart'; import 'package:manager_app/Components/message_notification.dart'; import 'package:manager_app/Components/rounded_input_field.dart'; import 'package:manager_app/Models/managerContext.dart'; import 'package:manager_app/Screens/Configurations/listView_card_section.dart'; import 'package:manager_app/Screens/Configurations/new_section_popup.dart'; import 'package:manager_app/app_context.dart'; import 'package:manager_app/constants.dart'; import 'package:manager_api_new/api.dart'; import 'package:provider/provider.dart'; /// Grille des sections d'une configuration, réordonnable. /// /// Elle était une liste horizontale enfermée dans `0,3 × hauteur d'écran` : /// 30 % de l'écran réservés quoi qu'il arrive, et les sections au-delà de la /// huitième hors champ à droite sans indice. Ici la grille se remplit sur toute /// la largeur et la hauteur suit le contenu. /// /// Le réordonnancement se fait par la poignée de chaque tuile /// (`Draggable` → `DragTarget`) : `ReorderableListView` ne sait pas faire de /// grille, et la maquette interdit une dépendance nouvelle. class SectionReorderList extends StatefulWidget { final String configurationId; final List sectionsIn; final ValueChanged> onChangedOrder; final Function askReload; const SectionReorderList({ Key? key, required this.configurationId, required this.sectionsIn, required this.onChangedOrder, required this.askReload, }) : super(key: key); @override _SectionReorderListState createState() => _SectionReorderListState(); } class _SectionReorderListState extends State { late List sections; String filterSearch = ''; @override void initState() { super.initState(); sections = new List.from(widget.sectionsIn); } void _onReorder(int oldIndex, int newIndex) { setState(() { final SectionDTO item = sections.removeAt(oldIndex); sections.insert(newIndex, item); var i = 0; sections.forEach((section) { section.order = i; i++; }); widget.onChangedOrder(sections); }); } Future _createSection(AppContext appContext) async { var sectionToCreate = await showNewSection(widget.configurationId, appContext, context, false); if (sectionToCreate != null) { ManagerAppContext managerAppContext = appContext.getContext(); sectionToCreate.instanceId = managerAppContext.instanceId; sectionToCreate.isBeacon = false; sectionToCreate.dateCreation = DateTime.now(); await managerAppContext.clientAPI!.sectionApi! .sectionCreate(sectionToCreate); showNotification(kSuccess, kWhite, AppLocalizations.of(context)!.sectionCreatedSuccess, context, null); widget.askReload(); } } /// Retirer une section de l'app sans la supprimer. Le champ existe depuis /// toujours côté serveur et les apps visiteur le respectent déjà — il n'avait /// simplement aucun geste dans le manager. Future _toggleVisibility( AppContext appContext, SectionDTO section) async { final l = AppLocalizations.of(context)!; final newValue = section.isActive == false; setState(() => section.isActive = newValue); try { ManagerAppContext managerAppContext = appContext.getContext(); await managerAppContext.clientAPI!.sectionApi! .sectionSetVisibility(section.id!, newValue); showNotification( kSuccess, kWhite, newValue ? l.sectionShownSuccess : l.sectionHiddenSuccess, context, null); } catch (e) { setState(() => section.isActive = !newValue); showNotification(kError, kWhite, l.sectionVisibilityError, context, null); } } @override Widget build(BuildContext context) { final appContext = Provider.of(context); final l = AppLocalizations.of(context)!; final canEdit = (appContext.getContext() as ManagerAppContext).canEdit; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ RoundedInputField( hintText: l.searchLabel, icon: Icons.search, onChanged: (String value) { setState(() { filterSearch = value; filterResource(); }); }, ), const SizedBox(height: kSpace4), SectionGrid( sections: sections, onReorder: _onReorder, onAdd: () => _createSection(appContext), onToggleVisibility: canEdit ? (section) => _toggleVisibility(appContext, section) : null, onTap: (section, index) { WidgetsBinding.instance.addPostFrameCallback((_) { setState(() { ManagerAppContext managerAppContext = appContext.getContext(); managerAppContext.selectedSection = section; appContext.setContext(managerAppContext); }); }); }, ), ], ); } void filterResource() { sections = filterSearch.isEmpty ? widget.sectionsIn: widget.sectionsIn.where((SectionDTO section) => removeDiacritics(section.label!.toUpperCase()).contains(removeDiacritics(filterSearch.toUpperCase()))).toList(); } }