194 lines
6.4 KiB
Dart
194 lines
6.4 KiB
Dart
import 'package:freezed_annotation/freezed_annotation.dart';
|
|
|
|
// ignore_for_file: invalid_annotation_target
|
|
|
|
part 'audit_log_model.freezed.dart';
|
|
part 'audit_log_model.g.dart';
|
|
|
|
String _idFromJson(Object? value) => value?.toString() ?? '';
|
|
|
|
String? _idFromJsonNullable(Object? value) {
|
|
if (value == null) return null;
|
|
final text = value.toString().trim();
|
|
return text.isEmpty ? null : text;
|
|
}
|
|
|
|
DateTime? _dateFromJsonNullable(Object? value) {
|
|
if (value == null) return null;
|
|
if (value is DateTime) return value;
|
|
return DateTime.tryParse(value.toString());
|
|
}
|
|
|
|
Map<String, dynamic>? _mapFromJsonNullable(Object? value) {
|
|
if (value == null) return null;
|
|
if (value is Map<String, dynamic>) return value;
|
|
if (value is Map) {
|
|
return value.map((key, val) => MapEntry(key.toString(), val));
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@freezed
|
|
class AuditLogUserModel with _$AuditLogUserModel {
|
|
const factory AuditLogUserModel({
|
|
@JsonKey(fromJson: _idFromJson) required String id,
|
|
@JsonKey(name: 'full_name') String? fullName,
|
|
@JsonKey(name: 'employee_code') String? employeeCode,
|
|
String? email,
|
|
}) = _AuditLogUserModel;
|
|
|
|
factory AuditLogUserModel.fromJson(Map<String, dynamic> json) =>
|
|
_$AuditLogUserModelFromJson(json);
|
|
}
|
|
|
|
@freezed
|
|
class AuditLogPerformerOption with _$AuditLogPerformerOption {
|
|
const factory AuditLogPerformerOption({
|
|
@JsonKey(fromJson: _idFromJson) required String id,
|
|
@JsonKey(name: 'full_name') String? fullName,
|
|
@JsonKey(name: 'employee_code') String? employeeCode,
|
|
}) = _AuditLogPerformerOption;
|
|
|
|
factory AuditLogPerformerOption.fromJson(Map<String, dynamic> json) =>
|
|
_$AuditLogPerformerOptionFromJson(json);
|
|
|
|
const AuditLogPerformerOption._();
|
|
|
|
String get label {
|
|
final name = fullName?.trim();
|
|
final code = employeeCode?.trim();
|
|
if (name != null && name.isNotEmpty && code != null && code.isNotEmpty) {
|
|
return '$name ($code)';
|
|
}
|
|
if (name != null && name.isNotEmpty) return name;
|
|
if (code != null && code.isNotEmpty) return code;
|
|
return id;
|
|
}
|
|
}
|
|
|
|
@freezed
|
|
class AuditLogFilterOptions with _$AuditLogFilterOptions {
|
|
const factory AuditLogFilterOptions({
|
|
@JsonKey(name: 'table_names') @Default([]) List<String> tableNames,
|
|
@Default([]) List<String> actions,
|
|
@Default([]) List<AuditLogPerformerOption> performers,
|
|
}) = _AuditLogFilterOptions;
|
|
|
|
factory AuditLogFilterOptions.fromJson(Map<String, dynamic> json) =>
|
|
_$AuditLogFilterOptionsFromJson(json);
|
|
}
|
|
|
|
@freezed
|
|
class AuditLogEntryModel with _$AuditLogEntryModel {
|
|
const factory AuditLogEntryModel({
|
|
@JsonKey(fromJson: _idFromJson) required String id,
|
|
@JsonKey(name: 'table_name') required String tableName,
|
|
@JsonKey(name: 'record_id', fromJson: _idFromJsonNullable) String? recordId,
|
|
required String action,
|
|
@JsonKey(name: 'performed_at', fromJson: _dateFromJsonNullable)
|
|
DateTime? performedAt,
|
|
@JsonKey(name: 'performed_by', fromJson: _idFromJsonNullable)
|
|
String? performedBy,
|
|
@JsonKey(name: 'request_id') String? requestId,
|
|
@JsonKey(name: 'performed_by_user') AuditLogUserModel? performedByUser,
|
|
@JsonKey(name: 'has_old_value') @Default(false) bool hasOldValue,
|
|
@JsonKey(name: 'has_new_value') @Default(false) bool hasNewValue,
|
|
}) = _AuditLogEntryModel;
|
|
|
|
factory AuditLogEntryModel.fromJson(Map<String, dynamic> json) =>
|
|
_$AuditLogEntryModelFromJson(json);
|
|
|
|
const AuditLogEntryModel._();
|
|
|
|
String get performerLabel {
|
|
final user = performedByUser;
|
|
if (user == null) return performedBy ?? '—';
|
|
final name = user.fullName?.trim();
|
|
final code = user.employeeCode?.trim();
|
|
if (name != null && name.isNotEmpty && code != null && code.isNotEmpty) {
|
|
return '$name ($code)';
|
|
}
|
|
if (name != null && name.isNotEmpty) return name;
|
|
return performedBy ?? '—';
|
|
}
|
|
}
|
|
|
|
@freezed
|
|
class AuditLogDetailModel with _$AuditLogDetailModel {
|
|
const factory AuditLogDetailModel({
|
|
@JsonKey(fromJson: _idFromJson) required String id,
|
|
@JsonKey(name: 'table_name') required String tableName,
|
|
@JsonKey(name: 'record_id', fromJson: _idFromJsonNullable) String? recordId,
|
|
required String action,
|
|
@JsonKey(name: 'performed_at', fromJson: _dateFromJsonNullable)
|
|
DateTime? performedAt,
|
|
@JsonKey(name: 'performed_by', fromJson: _idFromJsonNullable)
|
|
String? performedBy,
|
|
@JsonKey(name: 'request_id') String? requestId,
|
|
@JsonKey(name: 'performed_by_user') AuditLogUserModel? performedByUser,
|
|
@JsonKey(name: 'has_old_value') @Default(false) bool hasOldValue,
|
|
@JsonKey(name: 'has_new_value') @Default(false) bool hasNewValue,
|
|
@JsonKey(name: 'old_value', fromJson: _mapFromJsonNullable)
|
|
Map<String, dynamic>? oldValue,
|
|
@JsonKey(name: 'new_value', fromJson: _mapFromJsonNullable)
|
|
Map<String, dynamic>? newValue,
|
|
}) = _AuditLogDetailModel;
|
|
|
|
factory AuditLogDetailModel.fromJson(Map<String, dynamic> json) =>
|
|
_$AuditLogDetailModelFromJson(json);
|
|
|
|
const AuditLogDetailModel._();
|
|
|
|
String get performerLabel {
|
|
final user = performedByUser;
|
|
if (user == null) return performedBy ?? '—';
|
|
final name = user.fullName?.trim();
|
|
final code = user.employeeCode?.trim();
|
|
if (name != null && name.isNotEmpty && code != null && code.isNotEmpty) {
|
|
return '$name ($code)';
|
|
}
|
|
if (name != null && name.isNotEmpty) return name;
|
|
return performedBy ?? '—';
|
|
}
|
|
}
|
|
|
|
@freezed
|
|
class AuditLogListQuery with _$AuditLogListQuery {
|
|
const factory AuditLogListQuery({
|
|
@Default(1) int page,
|
|
@Default(20) int limit,
|
|
@JsonKey(name: 'table_name') String? tableName,
|
|
@JsonKey(name: 'record_id') int? recordId,
|
|
String? action,
|
|
@JsonKey(name: 'performed_by') int? performedBy,
|
|
@JsonKey(name: 'request_id') String? requestId,
|
|
@JsonKey(name: 'date_from') DateTime? dateFrom,
|
|
@JsonKey(name: 'date_to') DateTime? dateTo,
|
|
String? search,
|
|
}) = _AuditLogListQuery;
|
|
|
|
const AuditLogListQuery._();
|
|
|
|
bool get hasActiveFilter =>
|
|
(tableName?.isNotEmpty ?? false) ||
|
|
recordId != null ||
|
|
(action?.isNotEmpty ?? false) ||
|
|
performedBy != null ||
|
|
(requestId?.isNotEmpty ?? false) ||
|
|
dateFrom != null ||
|
|
dateTo != null ||
|
|
(search?.isNotEmpty ?? false);
|
|
}
|
|
|
|
@freezed
|
|
class AuditLogListResult with _$AuditLogListResult {
|
|
const factory AuditLogListResult({
|
|
@Default([]) List<AuditLogEntryModel> items,
|
|
@Default(1) int page,
|
|
@Default(20) int limit,
|
|
@Default(0) int total,
|
|
@Default(1) int totalPages,
|
|
@Default(false) bool filtersRequired,
|
|
}) = _AuditLogListResult;
|
|
}
|