add import export and items

This commit is contained in:
atseirjo
2026-10-28 08:10:55 +01:00
parent 07a1bb02fd
commit 4a1731f986
22 changed files with 1118 additions and 106 deletions
+1 -1
View File
@@ -13,7 +13,7 @@ class AnwendungForm extends StatelessWidget {
Widget build(BuildContext context) {
final filament = controller.filament.value!;
return EntryPanel(
title: 'Verarbeitung erfassen',
title: 'Verarbeitungsprofil bearbeiten',
subtitle:
'${filament.marke} · ${filament.material} · ${filament.farbe}\n'
'Speichere die Einstellungen für dieses Filament als Profil.',
+2 -23
View File
@@ -5,6 +5,7 @@ import 'package:intl/intl.dart';
import '../controller/home_controller.dart';
import '../theme/app_theme.dart';
import '../helper/input_validators.dart';
import 'filament_material_field.dart';
class FilamentForm extends StatelessWidget {
const FilamentForm({super.key, required this.controller});
@@ -130,29 +131,7 @@ class FilamentForm extends StatelessWidget {
: null,
),
const SizedBox(height: 16),
Obx(
() => DropdownButtonFormField<String>(
key: ValueKey(
'${controller.editingId.value ?? "new"}_${controller.material.value}',
),
initialValue: controller.material.value,
isExpanded: true,
decoration: const InputDecoration(
labelText: 'Material',
prefixIcon: Icon(Icons.layers_outlined),
),
items: controller.materialien
.toSet()
.map(
(item) =>
DropdownMenuItem(value: item, child: Text(item)),
)
.toList(),
onChanged: (value) {
if (value != null) controller.material.value = value;
},
),
),
FilamentMaterialField(controller: controller),
const SizedBox(height: 16),
TextFormField(
controller: controller.farbeController,
+126
View File
@@ -0,0 +1,126 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../controller/home_controller.dart';
class FilamentMaterialField extends StatelessWidget {
const FilamentMaterialField({super.key, required this.controller});
final HomeController controller;
@override
Widget build(BuildContext context) => Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
TextFormField(
controller: controller.materialController,
onChanged: (value) => controller.material.value = value,
validator: (value) => value == null || value.trim().isEmpty
? 'Materialart eingeben oder auswählen'
: null,
decoration: InputDecoration(
labelText: 'Material',
helperText: 'Auswählen oder eigene Art eingeben',
prefixIcon: const Icon(Icons.layers_outlined),
suffixIcon: Obx(
() => PopupMenuButton<String>(
tooltip: 'Material auswählen',
enabled: controller.materialien.isNotEmpty,
icon: const Icon(Icons.expand_more),
onSelected: controller.selectMaterial,
itemBuilder: (context) => controller.materialien
.map((item) => PopupMenuItem(value: item, child: Text(item)))
.toList(),
),
),
),
),
Obx(
() => Wrap(
spacing: 8,
children: [
TextButton.icon(
onPressed: controller.isSavingMaterial.value
? null
: () async {
if (await controller.addMaterial() && context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Art ist in der Liste.'),
),
);
}
},
icon: const Icon(Icons.add),
label: const Text('Art hinzufügen'),
),
TextButton.icon(
onPressed: () => _manage(context),
icon: const Icon(Icons.tune),
label: const Text('Arten verwalten'),
),
],
),
),
_message(),
],
);
Widget _message() => Obx(() {
final message = controller.materialMessage.value;
return message == null
? const SizedBox.shrink()
: Text(message, style: const TextStyle(color: Colors.red));
});
Future<void> _manage(BuildContext context) => showDialog<void>(
context: context,
builder: (context) => AlertDialog(
title: const Text('Materialarten verwalten'),
content: SizedBox(
width: 360,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const Text(
'Entfernte Arten verschwinden aus der Auswahl. Gespeicherte Filamente bleiben erhalten.',
),
const SizedBox(height: 12),
Flexible(
child: Obx(() {
final values = controller.materialien.toList();
final busy = controller.isSavingMaterial.value;
if (values.isEmpty) {
return const Text('Keine Materialarten in der Liste.');
}
return ListView.builder(
shrinkWrap: true,
itemCount: values.length,
itemBuilder: (context, index) => ListTile(
contentPadding: EdgeInsets.zero,
title: Text(values[index]),
trailing: IconButton(
tooltip: '${values[index]} aus Liste entfernen',
icon: const Icon(Icons.delete_outline),
onPressed: busy
? null
: () => controller.removeMaterial(values[index]),
),
),
);
}),
),
_message(),
],
),
),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: const Text('Schließen'),
),
],
),
);
}