search<T> static method

List<UserSearchResult<T>> search<T>({
  1. required Iterable<T> values,
  2. required Map<UserSearchField, String?> fieldsOf(
    1. T value
    ),
  3. required String accountIdOf(
    1. T value
    ),
  4. String query = '',
  5. List<UserSearchField> fieldOrder = teamFieldOrder,
})

Searches values using the supplied field and account projections.

Implementation

static List<UserSearchResult<T>> search<T>({
  required Iterable<T> values,
  required Map<UserSearchField, String?> Function(T value) fieldsOf,
  required String Function(T value) accountIdOf,
  String query = '',
  List<UserSearchField> fieldOrder = teamFieldOrder,
}) {
  final normalizedQuery = query.trim();
  final results = <UserSearchResult<T>>[];
  final seenAccountIds = <String>{};
  for (final value in values) {
    final fields = fieldsOf(value);
    final accountId = accountIdOf(value);
    if (accountId.isNotEmpty && !seenAccountIds.add(accountId)) {
      continue;
    }
    final primaryEntry = _firstNonEmpty(fields, fieldOrder);
    if (primaryEntry == null) {
      continue;
    }

    final matchesByField = <UserSearchField, List<SearchMatchRange>>{};
    if (normalizedQuery.isNotEmpty) {
      for (final field in fieldOrder) {
        final text = fields[field]?.trim();
        if (text == null || text.isEmpty) {
          continue;
        }
        final ranges = _findMatches(text, normalizedQuery, field);
        if (ranges.isNotEmpty) {
          matchesByField[field] = ranges;
        }
      }
      if (matchesByField.isEmpty) {
        continue;
      }
    }

    final lines = <SearchDisplayLine>[];
    final primaryMatches = matchesByField[primaryEntry.key] ?? const [];
    lines.add(SearchDisplayLine(
      text: primaryEntry.value,
      field: primaryEntry.key,
      matches: primaryMatches,
      isPrimary: true,
    ));
    if (normalizedQuery.isNotEmpty && primaryMatches.isEmpty) {
      for (final field in fieldOrder) {
        final matches = matchesByField[field];
        final text = fields[field]?.trim();
        if (matches != null && matches.isNotEmpty && text != null) {
          if (text != primaryEntry.value) {
            lines.add(SearchDisplayLine(
              text: text,
              field: field,
              matches: matches,
            ));
          }
          break;
        }
      }
    }
    results.add(UserSearchResult<T>(
      value: value,
      accountId: accountId,
      primaryName: primaryEntry.value,
      primaryField: primaryEntry.key,
      lines: lines,
    ));
  }
  return results;
}