feat: polish phase 7 forms and schedules
This commit is contained in:
101
lib/features/groups/group_form_logic.dart
Normal file
101
lib/features/groups/group_form_logic.dart
Normal file
@@ -0,0 +1,101 @@
|
||||
import '../../models/ignis_group.dart';
|
||||
|
||||
final RegExp _groupIdAllowedPattern = RegExp(r'^[a-z0-9][a-z0-9_-]*$');
|
||||
final RegExp _groupIdSanitizePattern = RegExp(r'[^a-z0-9_-]+');
|
||||
final RegExp _dashCollapsePattern = RegExp(r'[-_]{2,}');
|
||||
|
||||
const Map<String, String> _transliterationMap = {
|
||||
'а': 'a',
|
||||
'б': 'b',
|
||||
'в': 'v',
|
||||
'г': 'g',
|
||||
'д': 'd',
|
||||
'е': 'e',
|
||||
'ё': 'e',
|
||||
'ж': 'zh',
|
||||
'з': 'z',
|
||||
'и': 'i',
|
||||
'й': 'y',
|
||||
'к': 'k',
|
||||
'л': 'l',
|
||||
'м': 'm',
|
||||
'н': 'n',
|
||||
'о': 'o',
|
||||
'п': 'p',
|
||||
'р': 'r',
|
||||
'с': 's',
|
||||
'т': 't',
|
||||
'у': 'u',
|
||||
'ф': 'f',
|
||||
'х': 'h',
|
||||
'ц': 'ts',
|
||||
'ч': 'ch',
|
||||
'ш': 'sh',
|
||||
'щ': 'sch',
|
||||
'ъ': '',
|
||||
'ы': 'y',
|
||||
'ь': '',
|
||||
'э': 'e',
|
||||
'ю': 'yu',
|
||||
'я': 'ya',
|
||||
};
|
||||
|
||||
String slugifyGroupId(String input) {
|
||||
final lower = input.trim().toLowerCase();
|
||||
final buffer = StringBuffer();
|
||||
for (final rune in lower.runes) {
|
||||
final char = String.fromCharCode(rune);
|
||||
buffer.write(_transliterationMap[char] ?? char);
|
||||
}
|
||||
|
||||
var value = buffer
|
||||
.toString()
|
||||
.replaceAll(RegExp(r'\s+'), '-')
|
||||
.replaceAll(_groupIdSanitizePattern, '-')
|
||||
.replaceAll(_dashCollapsePattern, '-')
|
||||
.replaceAll(RegExp(r'^[-_]+|[-_]+$'), '');
|
||||
|
||||
if (value.length > 32) {
|
||||
value = value.substring(0, 32).replaceAll(RegExp(r'[-_]+$'), '');
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
String? validateGroupId(String value, Iterable<IgnisGroup> existingGroups) {
|
||||
final normalized = value.trim().toLowerCase();
|
||||
if (normalized.isEmpty) {
|
||||
return 'Укажите ID группы';
|
||||
}
|
||||
if (!_groupIdAllowedPattern.hasMatch(normalized)) {
|
||||
return 'Только латиница, цифры, "-" и "_"';
|
||||
}
|
||||
final alreadyExists = existingGroups.any((group) => group.id == normalized);
|
||||
if (alreadyExists) {
|
||||
return 'Группа с таким ID уже существует';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
String? validateGroupName(String value) {
|
||||
if (value.trim().isEmpty) {
|
||||
return 'Укажите название группы';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
List<IgnisGroup> findGroupMembershipConflicts(
|
||||
Set<String> selectedDeviceIds,
|
||||
Iterable<IgnisGroup> existingGroups,
|
||||
) {
|
||||
if (selectedDeviceIds.isEmpty) {
|
||||
return const [];
|
||||
}
|
||||
|
||||
return existingGroups
|
||||
.where(
|
||||
(group) =>
|
||||
group.macs.any((deviceId) => selectedDeviceIds.contains(deviceId)),
|
||||
)
|
||||
.toList();
|
||||
}
|
||||
Reference in New Issue
Block a user