Pflichtfeld-Kennzeichen (required) aus dem Workflow-Editor auswerten
- TourField/TourEntry um optionales required-Flag erweitert (Altdaten ohne Angabe verhalten sich unverändert) - Weiter-Button frei, wenn alle Pflichtfelder erfüllt sind oder der Task optional ist; Listen ohne Pflichtfelder (inkl. leerer Listen) sind frei - Pflichtfelder und Pflicht-Checkboxen mit rotem * markiert; Titel-* nur noch, wenn der Task tatsächlich zwingende Eingaben verlangt Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d864b9c72a
commit
f58f3f0c59
2 files changed
+92
-6
No files matched your search
@@ -215,7 +215,7 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
(taskInfo.task?.topic ?? '') + ((taskInfo.task?.opt ?? false) ? "" : " *"),
|
||||
(taskInfo.task?.topic ?? '') + (_isTaskOptional(taskInfo) ? "" : " *"),
|
||||
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
@@ -455,7 +455,16 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
|
||||
if ((fields[i].title ?? '').isNotEmpty)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 4, top: 4),
|
||||
child: Text(fields[i].title!, style: const TextStyle(fontWeight: FontWeight.w600)),
|
||||
child: Text.rich(
|
||||
TextSpan(
|
||||
text: fields[i].title!,
|
||||
children: [
|
||||
if (fields[i].required == true)
|
||||
const TextSpan(text: ' *', style: TextStyle(color: Colors.red)),
|
||||
],
|
||||
),
|
||||
style: const TextStyle(fontWeight: FontWeight.w600),
|
||||
),
|
||||
),
|
||||
Util.getDefaultTextField(
|
||||
fields[i].placeholder ?? '',
|
||||
@@ -485,7 +494,15 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
|
||||
contentPadding: EdgeInsets.zero,
|
||||
controlAffinity: ListTileControlAffinity.leading,
|
||||
activeColor: Constants.colorPrimary,
|
||||
title: Text(e.text),
|
||||
title: Text.rich(
|
||||
TextSpan(
|
||||
text: e.text,
|
||||
children: [
|
||||
if (e.required == true)
|
||||
const TextSpan(text: ' *', style: TextStyle(color: Colors.red)),
|
||||
],
|
||||
),
|
||||
),
|
||||
onChanged: (value) => setState(() {
|
||||
if (value ?? false) {
|
||||
draft.checked.add(e.code);
|
||||
@@ -616,6 +633,31 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
|
||||
return _isValid(taskInfo);
|
||||
}
|
||||
|
||||
/// Ob die Aufgabe insgesamt optional ist (steuert das "*" im Titel):
|
||||
/// entweder per {@code opt}-Flag oder – bei Listen-Tasks – weil kein
|
||||
/// einziger Eintrag als Pflichtfeld gekennzeichnet ist. Altdaten ohne
|
||||
/// Pflicht-Kennzeichen gelten wie bisher als verpflichtend.
|
||||
bool _isTaskOptional(TaskInfo taskInfo) {
|
||||
final task = taskInfo.task;
|
||||
if (task == null) return true;
|
||||
if (task.opt ?? false) return true;
|
||||
switch (task.type) {
|
||||
case 12:
|
||||
case 13:
|
||||
final fields = task.fields ?? [];
|
||||
if (fields.isEmpty) return true;
|
||||
if (fields.every((f) => f.required == null)) return false;
|
||||
return fields.every((f) => f.required != true);
|
||||
case 14:
|
||||
final entries = task.entries ?? [];
|
||||
if (entries.isEmpty) return true;
|
||||
if (entries.every((e) => e.required == null)) return false;
|
||||
return entries.every((e) => e.required != true);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool _isValid(TaskInfo taskInfo) {
|
||||
final draft = _draftFor(taskInfo);
|
||||
final type = taskInfo.task?.type ?? 0;
|
||||
@@ -647,17 +689,49 @@ class _TaskListPageState extends State<TaskListPage> with ProducerMixin {
|
||||
return true;
|
||||
case 12:
|
||||
_ensureFieldControllers(draft, taskInfo.task?.fields?.length ?? 0);
|
||||
return draft.fields.isNotEmpty && draft.fields.every((c) => c.text.trim().isNotEmpty);
|
||||
return _fieldsValid(taskInfo, draft, numeric: false);
|
||||
case 13:
|
||||
_ensureFieldControllers(draft, taskInfo.task?.fields?.length ?? 0);
|
||||
return draft.fields.isNotEmpty && draft.fields.every((c) => _isNumeric(c.text));
|
||||
return _fieldsValid(taskInfo, draft, numeric: true);
|
||||
case 14:
|
||||
return draft.checked.isNotEmpty;
|
||||
final entries = taskInfo.task?.entries ?? [];
|
||||
// Ohne definierte Einträge gibt es keine Pflichtfelder -> freigeben.
|
||||
if (entries.isEmpty) return true;
|
||||
// Altdaten ohne Pflicht-Kennzeichen: wie bisher mindestens ein Häkchen.
|
||||
if (entries.every((e) => e.required == null)) {
|
||||
return draft.checked.isNotEmpty;
|
||||
}
|
||||
return entries
|
||||
.where((e) => e.required == true)
|
||||
.every((e) => draft.checked.contains(e.code));
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// Prüft die Eingabefelder einer Text-/Zahlen-Liste (Typ 12/13) gegen ihre
|
||||
/// Pflicht-Kennzeichen. Altdaten ohne Kennzeichen behalten das bisherige
|
||||
/// Verhalten (alle Felder müssen gefüllt bzw. numerisch sein). Sonst müssen
|
||||
/// nur Pflichtfelder gefüllt (bei Zahlenlisten numerisch) sein; optionale
|
||||
/// Felder dürfen leer bleiben, müssen aber – falls ausgefüllt – bei
|
||||
/// Zahlenlisten ebenfalls numerisch sein.
|
||||
bool _fieldsValid(TaskInfo taskInfo, _TaskDraft draft, {required bool numeric}) {
|
||||
final fields = taskInfo.task?.fields ?? [];
|
||||
// Ohne definierte Felder gibt es keine Pflichtfelder -> freigeben.
|
||||
if (fields.isEmpty) return true;
|
||||
final legacy = fields.every((f) => f.required == null);
|
||||
for (int i = 0; i < fields.length && i < draft.fields.length; i++) {
|
||||
final text = draft.fields[i].text.trim();
|
||||
final mandatory = legacy || fields[i].required == true;
|
||||
if (mandatory) {
|
||||
if (numeric ? !_isNumeric(text) : text.isEmpty) return false;
|
||||
} else if (numeric && text.isNotEmpty && !_isNumeric(text)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Ob der Bearbeiter überhaupt Daten erfasst hat (für optionale Aufgaben:
|
||||
/// entscheidet, ob eine Antwort geschrieben oder die Aufgabe übersprungen wird).
|
||||
bool _hasData(TaskInfo taskInfo) {
|
||||
|
||||
Reference in new issue
Block a user