feat(device-management): add app usage schedules feature
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
import 'package:device_management/src/core/data/models/app_usage_schedule_response_dto.dart';
|
||||
import 'package:device_management/src/core/domain/entities/app_usage_schedule_entity.dart';
|
||||
|
||||
abstract class AppUsageSchedulesRemoteDatasource {
|
||||
Future<AppUsageScheduleResponseDto> getSchedules({
|
||||
required String identificator,
|
||||
});
|
||||
|
||||
Future<AppUsageScheduleResponseDto> upsertSchedules({
|
||||
required String identificator,
|
||||
required List<AppUsageSchedulePeriodEntity> periods,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
import 'package:device_management/src/core/data/datasources/app_usage_schedules_remote_datasource.dart';
|
||||
import 'package:device_management/src/core/data/models/app_usage_schedule_response_dto.dart';
|
||||
import 'package:device_management/src/core/domain/entities/app_usage_schedule_entity.dart';
|
||||
import 'package:sf_infrastructure/sf_infrastructure.dart';
|
||||
|
||||
class AppUsageSchedulesRemoteDatasourceImpl
|
||||
implements AppUsageSchedulesRemoteDatasource {
|
||||
AppUsageSchedulesRemoteDatasourceImpl(this._repository);
|
||||
|
||||
final SaveFamilyRepository _repository;
|
||||
|
||||
@override
|
||||
Future<AppUsageScheduleResponseDto> getSchedules({
|
||||
required String identificator,
|
||||
}) async {
|
||||
final response = await safeCall(
|
||||
() => _repository.get<Map<String, dynamic>>(
|
||||
'/devices/identificator/$identificator/app-usage-schedules',
|
||||
),
|
||||
'Error getting app usage schedules',
|
||||
);
|
||||
|
||||
final data = response.data;
|
||||
if (data == null || data.isEmpty) {
|
||||
throw const ApiException(message: 'Empty response', statusCode: 404);
|
||||
}
|
||||
|
||||
final item = data['item'] as Map<String, dynamic>?;
|
||||
if (item == null) {
|
||||
throw const ApiException(message: 'No item in response', statusCode: 404);
|
||||
}
|
||||
|
||||
return AppUsageScheduleResponseDto.fromJson(item);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<AppUsageScheduleResponseDto> upsertSchedules({
|
||||
required String identificator,
|
||||
required List<AppUsageSchedulePeriodEntity> periods,
|
||||
}) async {
|
||||
final response = await safeCall(
|
||||
() => _repository.put<Map<String, dynamic>>(
|
||||
'/devices/identificator/$identificator/app-usage-schedules',
|
||||
body: <String, dynamic>{
|
||||
'periods': periods
|
||||
.map(
|
||||
(p) => <String, dynamic>{
|
||||
'periodStart': p.periodStart,
|
||||
'periodEnd': p.periodEnd,
|
||||
'isPeriodEnabled': p.isPeriodEnabled,
|
||||
},
|
||||
)
|
||||
.toList(),
|
||||
},
|
||||
),
|
||||
'Error saving app usage schedules',
|
||||
);
|
||||
|
||||
final data = response.data;
|
||||
if (data == null || data.isEmpty) {
|
||||
throw const ApiException(message: 'Empty response');
|
||||
}
|
||||
|
||||
final item = data['item'] as Map<String, dynamic>?;
|
||||
if (item == null) {
|
||||
throw const ApiException(message: 'No item in response');
|
||||
}
|
||||
|
||||
return AppUsageScheduleResponseDto.fromJson(item);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
import 'package:device_management/src/core/domain/entities/app_usage_schedule_entity.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'app_usage_schedule_response_dto.freezed.dart';
|
||||
part 'app_usage_schedule_response_dto.g.dart';
|
||||
|
||||
@freezed
|
||||
abstract class AppUsageScheduleResponseDto
|
||||
with _$AppUsageScheduleResponseDto {
|
||||
const factory AppUsageScheduleResponseDto({
|
||||
required String id,
|
||||
required String deviceIdentificator,
|
||||
required List<AppUsageSchedulePeriodDto> periods,
|
||||
required int createdAt,
|
||||
int? updatedAt,
|
||||
}) = _AppUsageScheduleResponseDto;
|
||||
|
||||
factory AppUsageScheduleResponseDto.fromJson(Map<String, dynamic> json) =>
|
||||
_$AppUsageScheduleResponseDtoFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class AppUsageSchedulePeriodDto with _$AppUsageSchedulePeriodDto {
|
||||
const factory AppUsageSchedulePeriodDto({
|
||||
required String periodStart,
|
||||
required String periodEnd,
|
||||
required bool isPeriodEnabled,
|
||||
}) = _AppUsageSchedulePeriodDto;
|
||||
|
||||
factory AppUsageSchedulePeriodDto.fromJson(Map<String, dynamic> json) =>
|
||||
_$AppUsageSchedulePeriodDtoFromJson(json);
|
||||
}
|
||||
|
||||
extension AppUsageScheduleResponseDtoX on AppUsageScheduleResponseDto {
|
||||
List<AppUsageSchedulePeriodEntity> toEntities() {
|
||||
return periods
|
||||
.map(
|
||||
(p) => AppUsageSchedulePeriodEntity(
|
||||
periodStart: p.periodStart,
|
||||
periodEnd: p.periodEnd,
|
||||
isPeriodEnabled: p.isPeriodEnabled,
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,564 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'app_usage_schedule_response_dto.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
|
||||
/// @nodoc
|
||||
mixin _$AppUsageScheduleResponseDto {
|
||||
|
||||
String get id; String get deviceIdentificator; List<AppUsageSchedulePeriodDto> get periods; int get createdAt; int? get updatedAt;
|
||||
/// Create a copy of AppUsageScheduleResponseDto
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$AppUsageScheduleResponseDtoCopyWith<AppUsageScheduleResponseDto> get copyWith => _$AppUsageScheduleResponseDtoCopyWithImpl<AppUsageScheduleResponseDto>(this as AppUsageScheduleResponseDto, _$identity);
|
||||
|
||||
/// Serializes this AppUsageScheduleResponseDto to a JSON map.
|
||||
Map<String, dynamic> toJson();
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is AppUsageScheduleResponseDto&&(identical(other.id, id) || other.id == id)&&(identical(other.deviceIdentificator, deviceIdentificator) || other.deviceIdentificator == deviceIdentificator)&&const DeepCollectionEquality().equals(other.periods, periods)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,id,deviceIdentificator,const DeepCollectionEquality().hash(periods),createdAt,updatedAt);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'AppUsageScheduleResponseDto(id: $id, deviceIdentificator: $deviceIdentificator, periods: $periods, createdAt: $createdAt, updatedAt: $updatedAt)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $AppUsageScheduleResponseDtoCopyWith<$Res> {
|
||||
factory $AppUsageScheduleResponseDtoCopyWith(AppUsageScheduleResponseDto value, $Res Function(AppUsageScheduleResponseDto) _then) = _$AppUsageScheduleResponseDtoCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String id, String deviceIdentificator, List<AppUsageSchedulePeriodDto> periods, int createdAt, int? updatedAt
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$AppUsageScheduleResponseDtoCopyWithImpl<$Res>
|
||||
implements $AppUsageScheduleResponseDtoCopyWith<$Res> {
|
||||
_$AppUsageScheduleResponseDtoCopyWithImpl(this._self, this._then);
|
||||
|
||||
final AppUsageScheduleResponseDto _self;
|
||||
final $Res Function(AppUsageScheduleResponseDto) _then;
|
||||
|
||||
/// Create a copy of AppUsageScheduleResponseDto
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? deviceIdentificator = null,Object? periods = null,Object? createdAt = null,Object? updatedAt = freezed,}) {
|
||||
return _then(_self.copyWith(
|
||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,deviceIdentificator: null == deviceIdentificator ? _self.deviceIdentificator : deviceIdentificator // ignore: cast_nullable_to_non_nullable
|
||||
as String,periods: null == periods ? _self.periods : periods // ignore: cast_nullable_to_non_nullable
|
||||
as List<AppUsageSchedulePeriodDto>,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||
as int,updatedAt: freezed == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||
as int?,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [AppUsageScheduleResponseDto].
|
||||
extension AppUsageScheduleResponseDtoPatterns on AppUsageScheduleResponseDto {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _AppUsageScheduleResponseDto value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _AppUsageScheduleResponseDto() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _AppUsageScheduleResponseDto value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _AppUsageScheduleResponseDto():
|
||||
return $default(_that);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _AppUsageScheduleResponseDto value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _AppUsageScheduleResponseDto() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String deviceIdentificator, List<AppUsageSchedulePeriodDto> periods, int createdAt, int? updatedAt)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _AppUsageScheduleResponseDto() when $default != null:
|
||||
return $default(_that.id,_that.deviceIdentificator,_that.periods,_that.createdAt,_that.updatedAt);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String deviceIdentificator, List<AppUsageSchedulePeriodDto> periods, int createdAt, int? updatedAt) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _AppUsageScheduleResponseDto():
|
||||
return $default(_that.id,_that.deviceIdentificator,_that.periods,_that.createdAt,_that.updatedAt);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String deviceIdentificator, List<AppUsageSchedulePeriodDto> periods, int createdAt, int? updatedAt)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _AppUsageScheduleResponseDto() when $default != null:
|
||||
return $default(_that.id,_that.deviceIdentificator,_that.periods,_that.createdAt,_that.updatedAt);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
|
||||
class _AppUsageScheduleResponseDto implements AppUsageScheduleResponseDto {
|
||||
const _AppUsageScheduleResponseDto({required this.id, required this.deviceIdentificator, required final List<AppUsageSchedulePeriodDto> periods, required this.createdAt, this.updatedAt}): _periods = periods;
|
||||
factory _AppUsageScheduleResponseDto.fromJson(Map<String, dynamic> json) => _$AppUsageScheduleResponseDtoFromJson(json);
|
||||
|
||||
@override final String id;
|
||||
@override final String deviceIdentificator;
|
||||
final List<AppUsageSchedulePeriodDto> _periods;
|
||||
@override List<AppUsageSchedulePeriodDto> get periods {
|
||||
if (_periods is EqualUnmodifiableListView) return _periods;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_periods);
|
||||
}
|
||||
|
||||
@override final int createdAt;
|
||||
@override final int? updatedAt;
|
||||
|
||||
/// Create a copy of AppUsageScheduleResponseDto
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$AppUsageScheduleResponseDtoCopyWith<_AppUsageScheduleResponseDto> get copyWith => __$AppUsageScheduleResponseDtoCopyWithImpl<_AppUsageScheduleResponseDto>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$AppUsageScheduleResponseDtoToJson(this, );
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _AppUsageScheduleResponseDto&&(identical(other.id, id) || other.id == id)&&(identical(other.deviceIdentificator, deviceIdentificator) || other.deviceIdentificator == deviceIdentificator)&&const DeepCollectionEquality().equals(other._periods, _periods)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,id,deviceIdentificator,const DeepCollectionEquality().hash(_periods),createdAt,updatedAt);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'AppUsageScheduleResponseDto(id: $id, deviceIdentificator: $deviceIdentificator, periods: $periods, createdAt: $createdAt, updatedAt: $updatedAt)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$AppUsageScheduleResponseDtoCopyWith<$Res> implements $AppUsageScheduleResponseDtoCopyWith<$Res> {
|
||||
factory _$AppUsageScheduleResponseDtoCopyWith(_AppUsageScheduleResponseDto value, $Res Function(_AppUsageScheduleResponseDto) _then) = __$AppUsageScheduleResponseDtoCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String id, String deviceIdentificator, List<AppUsageSchedulePeriodDto> periods, int createdAt, int? updatedAt
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$AppUsageScheduleResponseDtoCopyWithImpl<$Res>
|
||||
implements _$AppUsageScheduleResponseDtoCopyWith<$Res> {
|
||||
__$AppUsageScheduleResponseDtoCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _AppUsageScheduleResponseDto _self;
|
||||
final $Res Function(_AppUsageScheduleResponseDto) _then;
|
||||
|
||||
/// Create a copy of AppUsageScheduleResponseDto
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? deviceIdentificator = null,Object? periods = null,Object? createdAt = null,Object? updatedAt = freezed,}) {
|
||||
return _then(_AppUsageScheduleResponseDto(
|
||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,deviceIdentificator: null == deviceIdentificator ? _self.deviceIdentificator : deviceIdentificator // ignore: cast_nullable_to_non_nullable
|
||||
as String,periods: null == periods ? _self._periods : periods // ignore: cast_nullable_to_non_nullable
|
||||
as List<AppUsageSchedulePeriodDto>,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||
as int,updatedAt: freezed == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||
as int?,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// @nodoc
|
||||
mixin _$AppUsageSchedulePeriodDto {
|
||||
|
||||
String get periodStart; String get periodEnd; bool get isPeriodEnabled;
|
||||
/// Create a copy of AppUsageSchedulePeriodDto
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$AppUsageSchedulePeriodDtoCopyWith<AppUsageSchedulePeriodDto> get copyWith => _$AppUsageSchedulePeriodDtoCopyWithImpl<AppUsageSchedulePeriodDto>(this as AppUsageSchedulePeriodDto, _$identity);
|
||||
|
||||
/// Serializes this AppUsageSchedulePeriodDto to a JSON map.
|
||||
Map<String, dynamic> toJson();
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is AppUsageSchedulePeriodDto&&(identical(other.periodStart, periodStart) || other.periodStart == periodStart)&&(identical(other.periodEnd, periodEnd) || other.periodEnd == periodEnd)&&(identical(other.isPeriodEnabled, isPeriodEnabled) || other.isPeriodEnabled == isPeriodEnabled));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,periodStart,periodEnd,isPeriodEnabled);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'AppUsageSchedulePeriodDto(periodStart: $periodStart, periodEnd: $periodEnd, isPeriodEnabled: $isPeriodEnabled)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $AppUsageSchedulePeriodDtoCopyWith<$Res> {
|
||||
factory $AppUsageSchedulePeriodDtoCopyWith(AppUsageSchedulePeriodDto value, $Res Function(AppUsageSchedulePeriodDto) _then) = _$AppUsageSchedulePeriodDtoCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String periodStart, String periodEnd, bool isPeriodEnabled
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$AppUsageSchedulePeriodDtoCopyWithImpl<$Res>
|
||||
implements $AppUsageSchedulePeriodDtoCopyWith<$Res> {
|
||||
_$AppUsageSchedulePeriodDtoCopyWithImpl(this._self, this._then);
|
||||
|
||||
final AppUsageSchedulePeriodDto _self;
|
||||
final $Res Function(AppUsageSchedulePeriodDto) _then;
|
||||
|
||||
/// Create a copy of AppUsageSchedulePeriodDto
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? periodStart = null,Object? periodEnd = null,Object? isPeriodEnabled = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
periodStart: null == periodStart ? _self.periodStart : periodStart // ignore: cast_nullable_to_non_nullable
|
||||
as String,periodEnd: null == periodEnd ? _self.periodEnd : periodEnd // ignore: cast_nullable_to_non_nullable
|
||||
as String,isPeriodEnabled: null == isPeriodEnabled ? _self.isPeriodEnabled : isPeriodEnabled // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [AppUsageSchedulePeriodDto].
|
||||
extension AppUsageSchedulePeriodDtoPatterns on AppUsageSchedulePeriodDto {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _AppUsageSchedulePeriodDto value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _AppUsageSchedulePeriodDto() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _AppUsageSchedulePeriodDto value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _AppUsageSchedulePeriodDto():
|
||||
return $default(_that);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _AppUsageSchedulePeriodDto value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _AppUsageSchedulePeriodDto() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String periodStart, String periodEnd, bool isPeriodEnabled)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _AppUsageSchedulePeriodDto() when $default != null:
|
||||
return $default(_that.periodStart,_that.periodEnd,_that.isPeriodEnabled);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String periodStart, String periodEnd, bool isPeriodEnabled) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _AppUsageSchedulePeriodDto():
|
||||
return $default(_that.periodStart,_that.periodEnd,_that.isPeriodEnabled);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String periodStart, String periodEnd, bool isPeriodEnabled)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _AppUsageSchedulePeriodDto() when $default != null:
|
||||
return $default(_that.periodStart,_that.periodEnd,_that.isPeriodEnabled);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
|
||||
class _AppUsageSchedulePeriodDto implements AppUsageSchedulePeriodDto {
|
||||
const _AppUsageSchedulePeriodDto({required this.periodStart, required this.periodEnd, required this.isPeriodEnabled});
|
||||
factory _AppUsageSchedulePeriodDto.fromJson(Map<String, dynamic> json) => _$AppUsageSchedulePeriodDtoFromJson(json);
|
||||
|
||||
@override final String periodStart;
|
||||
@override final String periodEnd;
|
||||
@override final bool isPeriodEnabled;
|
||||
|
||||
/// Create a copy of AppUsageSchedulePeriodDto
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$AppUsageSchedulePeriodDtoCopyWith<_AppUsageSchedulePeriodDto> get copyWith => __$AppUsageSchedulePeriodDtoCopyWithImpl<_AppUsageSchedulePeriodDto>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$AppUsageSchedulePeriodDtoToJson(this, );
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _AppUsageSchedulePeriodDto&&(identical(other.periodStart, periodStart) || other.periodStart == periodStart)&&(identical(other.periodEnd, periodEnd) || other.periodEnd == periodEnd)&&(identical(other.isPeriodEnabled, isPeriodEnabled) || other.isPeriodEnabled == isPeriodEnabled));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,periodStart,periodEnd,isPeriodEnabled);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'AppUsageSchedulePeriodDto(periodStart: $periodStart, periodEnd: $periodEnd, isPeriodEnabled: $isPeriodEnabled)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$AppUsageSchedulePeriodDtoCopyWith<$Res> implements $AppUsageSchedulePeriodDtoCopyWith<$Res> {
|
||||
factory _$AppUsageSchedulePeriodDtoCopyWith(_AppUsageSchedulePeriodDto value, $Res Function(_AppUsageSchedulePeriodDto) _then) = __$AppUsageSchedulePeriodDtoCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String periodStart, String periodEnd, bool isPeriodEnabled
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$AppUsageSchedulePeriodDtoCopyWithImpl<$Res>
|
||||
implements _$AppUsageSchedulePeriodDtoCopyWith<$Res> {
|
||||
__$AppUsageSchedulePeriodDtoCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _AppUsageSchedulePeriodDto _self;
|
||||
final $Res Function(_AppUsageSchedulePeriodDto) _then;
|
||||
|
||||
/// Create a copy of AppUsageSchedulePeriodDto
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? periodStart = null,Object? periodEnd = null,Object? isPeriodEnabled = null,}) {
|
||||
return _then(_AppUsageSchedulePeriodDto(
|
||||
periodStart: null == periodStart ? _self.periodStart : periodStart // ignore: cast_nullable_to_non_nullable
|
||||
as String,periodEnd: null == periodEnd ? _self.periodEnd : periodEnd // ignore: cast_nullable_to_non_nullable
|
||||
as String,isPeriodEnabled: null == isPeriodEnabled ? _self.isPeriodEnabled : isPeriodEnabled // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -0,0 +1,45 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'app_usage_schedule_response_dto.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_AppUsageScheduleResponseDto _$AppUsageScheduleResponseDtoFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _AppUsageScheduleResponseDto(
|
||||
id: json['id'] as String,
|
||||
deviceIdentificator: json['deviceIdentificator'] as String,
|
||||
periods: (json['periods'] as List<dynamic>)
|
||||
.map((e) => AppUsageSchedulePeriodDto.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
createdAt: (json['createdAt'] as num).toInt(),
|
||||
updatedAt: (json['updatedAt'] as num?)?.toInt(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$AppUsageScheduleResponseDtoToJson(
|
||||
_AppUsageScheduleResponseDto instance,
|
||||
) => <String, dynamic>{
|
||||
'id': instance.id,
|
||||
'deviceIdentificator': instance.deviceIdentificator,
|
||||
'periods': instance.periods,
|
||||
'createdAt': instance.createdAt,
|
||||
'updatedAt': instance.updatedAt,
|
||||
};
|
||||
|
||||
_AppUsageSchedulePeriodDto _$AppUsageSchedulePeriodDtoFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _AppUsageSchedulePeriodDto(
|
||||
periodStart: json['periodStart'] as String,
|
||||
periodEnd: json['periodEnd'] as String,
|
||||
isPeriodEnabled: json['isPeriodEnabled'] as bool,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$AppUsageSchedulePeriodDtoToJson(
|
||||
_AppUsageSchedulePeriodDto instance,
|
||||
) => <String, dynamic>{
|
||||
'periodStart': instance.periodStart,
|
||||
'periodEnd': instance.periodEnd,
|
||||
'isPeriodEnabled': instance.isPeriodEnabled,
|
||||
};
|
||||
@@ -0,0 +1,42 @@
|
||||
import 'package:device_management/src/core/data/datasources/app_usage_schedules_remote_datasource.dart';
|
||||
import 'package:device_management/src/core/data/models/app_usage_schedule_response_dto.dart';
|
||||
import 'package:device_management/src/core/domain/entities/app_usage_schedule_entity.dart';
|
||||
import 'package:device_management/src/core/domain/repositories/app_usage_schedules_repository.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:sf_infrastructure/sf_infrastructure.dart';
|
||||
|
||||
class AppUsageSchedulesRepositoryImpl implements AppUsageSchedulesRepository {
|
||||
AppUsageSchedulesRepositoryImpl(this._remote);
|
||||
|
||||
final AppUsageSchedulesRemoteDatasource _remote;
|
||||
|
||||
@override
|
||||
Future<List<AppUsageSchedulePeriodEntity>> getSchedules({
|
||||
required String identificator,
|
||||
}) async {
|
||||
try {
|
||||
final response = await _remote.getSchedules(
|
||||
identificator: identificator,
|
||||
);
|
||||
return response.toEntities();
|
||||
} on ApiException catch (e) {
|
||||
if (e.statusCode == 404) return [];
|
||||
rethrow;
|
||||
} on DioException catch (e) {
|
||||
if (e.response?.statusCode == 404) return [];
|
||||
throw mapDioError(e, defaultMessage: 'Error getting schedules');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<AppUsageSchedulePeriodEntity>> upsertSchedules({
|
||||
required String identificator,
|
||||
required List<AppUsageSchedulePeriodEntity> periods,
|
||||
}) async {
|
||||
final response = await _remote.upsertSchedules(
|
||||
identificator: identificator,
|
||||
periods: periods,
|
||||
);
|
||||
return response.toEntities();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'app_usage_schedule_entity.freezed.dart';
|
||||
|
||||
@freezed
|
||||
abstract class AppUsageSchedulePeriodEntity
|
||||
with _$AppUsageSchedulePeriodEntity {
|
||||
const factory AppUsageSchedulePeriodEntity({
|
||||
required String periodStart,
|
||||
required String periodEnd,
|
||||
required bool isPeriodEnabled,
|
||||
}) = _AppUsageSchedulePeriodEntity;
|
||||
}
|
||||
@@ -0,0 +1,277 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'app_usage_schedule_entity.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$AppUsageSchedulePeriodEntity {
|
||||
|
||||
String get periodStart; String get periodEnd; bool get isPeriodEnabled;
|
||||
/// Create a copy of AppUsageSchedulePeriodEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$AppUsageSchedulePeriodEntityCopyWith<AppUsageSchedulePeriodEntity> get copyWith => _$AppUsageSchedulePeriodEntityCopyWithImpl<AppUsageSchedulePeriodEntity>(this as AppUsageSchedulePeriodEntity, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is AppUsageSchedulePeriodEntity&&(identical(other.periodStart, periodStart) || other.periodStart == periodStart)&&(identical(other.periodEnd, periodEnd) || other.periodEnd == periodEnd)&&(identical(other.isPeriodEnabled, isPeriodEnabled) || other.isPeriodEnabled == isPeriodEnabled));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,periodStart,periodEnd,isPeriodEnabled);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'AppUsageSchedulePeriodEntity(periodStart: $periodStart, periodEnd: $periodEnd, isPeriodEnabled: $isPeriodEnabled)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $AppUsageSchedulePeriodEntityCopyWith<$Res> {
|
||||
factory $AppUsageSchedulePeriodEntityCopyWith(AppUsageSchedulePeriodEntity value, $Res Function(AppUsageSchedulePeriodEntity) _then) = _$AppUsageSchedulePeriodEntityCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String periodStart, String periodEnd, bool isPeriodEnabled
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$AppUsageSchedulePeriodEntityCopyWithImpl<$Res>
|
||||
implements $AppUsageSchedulePeriodEntityCopyWith<$Res> {
|
||||
_$AppUsageSchedulePeriodEntityCopyWithImpl(this._self, this._then);
|
||||
|
||||
final AppUsageSchedulePeriodEntity _self;
|
||||
final $Res Function(AppUsageSchedulePeriodEntity) _then;
|
||||
|
||||
/// Create a copy of AppUsageSchedulePeriodEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? periodStart = null,Object? periodEnd = null,Object? isPeriodEnabled = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
periodStart: null == periodStart ? _self.periodStart : periodStart // ignore: cast_nullable_to_non_nullable
|
||||
as String,periodEnd: null == periodEnd ? _self.periodEnd : periodEnd // ignore: cast_nullable_to_non_nullable
|
||||
as String,isPeriodEnabled: null == isPeriodEnabled ? _self.isPeriodEnabled : isPeriodEnabled // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [AppUsageSchedulePeriodEntity].
|
||||
extension AppUsageSchedulePeriodEntityPatterns on AppUsageSchedulePeriodEntity {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _AppUsageSchedulePeriodEntity value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _AppUsageSchedulePeriodEntity() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _AppUsageSchedulePeriodEntity value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _AppUsageSchedulePeriodEntity():
|
||||
return $default(_that);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _AppUsageSchedulePeriodEntity value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _AppUsageSchedulePeriodEntity() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String periodStart, String periodEnd, bool isPeriodEnabled)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _AppUsageSchedulePeriodEntity() when $default != null:
|
||||
return $default(_that.periodStart,_that.periodEnd,_that.isPeriodEnabled);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String periodStart, String periodEnd, bool isPeriodEnabled) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _AppUsageSchedulePeriodEntity():
|
||||
return $default(_that.periodStart,_that.periodEnd,_that.isPeriodEnabled);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String periodStart, String periodEnd, bool isPeriodEnabled)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _AppUsageSchedulePeriodEntity() when $default != null:
|
||||
return $default(_that.periodStart,_that.periodEnd,_that.isPeriodEnabled);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _AppUsageSchedulePeriodEntity implements AppUsageSchedulePeriodEntity {
|
||||
const _AppUsageSchedulePeriodEntity({required this.periodStart, required this.periodEnd, required this.isPeriodEnabled});
|
||||
|
||||
|
||||
@override final String periodStart;
|
||||
@override final String periodEnd;
|
||||
@override final bool isPeriodEnabled;
|
||||
|
||||
/// Create a copy of AppUsageSchedulePeriodEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$AppUsageSchedulePeriodEntityCopyWith<_AppUsageSchedulePeriodEntity> get copyWith => __$AppUsageSchedulePeriodEntityCopyWithImpl<_AppUsageSchedulePeriodEntity>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _AppUsageSchedulePeriodEntity&&(identical(other.periodStart, periodStart) || other.periodStart == periodStart)&&(identical(other.periodEnd, periodEnd) || other.periodEnd == periodEnd)&&(identical(other.isPeriodEnabled, isPeriodEnabled) || other.isPeriodEnabled == isPeriodEnabled));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,periodStart,periodEnd,isPeriodEnabled);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'AppUsageSchedulePeriodEntity(periodStart: $periodStart, periodEnd: $periodEnd, isPeriodEnabled: $isPeriodEnabled)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$AppUsageSchedulePeriodEntityCopyWith<$Res> implements $AppUsageSchedulePeriodEntityCopyWith<$Res> {
|
||||
factory _$AppUsageSchedulePeriodEntityCopyWith(_AppUsageSchedulePeriodEntity value, $Res Function(_AppUsageSchedulePeriodEntity) _then) = __$AppUsageSchedulePeriodEntityCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String periodStart, String periodEnd, bool isPeriodEnabled
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$AppUsageSchedulePeriodEntityCopyWithImpl<$Res>
|
||||
implements _$AppUsageSchedulePeriodEntityCopyWith<$Res> {
|
||||
__$AppUsageSchedulePeriodEntityCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _AppUsageSchedulePeriodEntity _self;
|
||||
final $Res Function(_AppUsageSchedulePeriodEntity) _then;
|
||||
|
||||
/// Create a copy of AppUsageSchedulePeriodEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? periodStart = null,Object? periodEnd = null,Object? isPeriodEnabled = null,}) {
|
||||
return _then(_AppUsageSchedulePeriodEntity(
|
||||
periodStart: null == periodStart ? _self.periodStart : periodStart // ignore: cast_nullable_to_non_nullable
|
||||
as String,periodEnd: null == periodEnd ? _self.periodEnd : periodEnd // ignore: cast_nullable_to_non_nullable
|
||||
as String,isPeriodEnabled: null == isPeriodEnabled ? _self.isPeriodEnabled : isPeriodEnabled // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -0,0 +1,12 @@
|
||||
import 'package:device_management/src/core/domain/entities/app_usage_schedule_entity.dart';
|
||||
|
||||
abstract class AppUsageSchedulesRepository {
|
||||
Future<List<AppUsageSchedulePeriodEntity>> getSchedules({
|
||||
required String identificator,
|
||||
});
|
||||
|
||||
Future<List<AppUsageSchedulePeriodEntity>> upsertSchedules({
|
||||
required String identificator,
|
||||
required List<AppUsageSchedulePeriodEntity> periods,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import 'package:device_management/src/core/data/datasources/app_usage_schedules_remote_datasource_impl.dart';
|
||||
import 'package:device_management/src/core/data/repositories/app_usage_schedules_repository_impl.dart';
|
||||
import 'package:device_management/src/core/domain/repositories/app_usage_schedules_repository.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:sf_infrastructure/sf_infrastructure.dart';
|
||||
|
||||
final appUsageSchedulesRepositoryProvider =
|
||||
Provider<AppUsageSchedulesRepository>((ref) {
|
||||
final remote =
|
||||
AppUsageSchedulesRemoteDatasourceImpl(getIt<SaveFamilyRepository>());
|
||||
return AppUsageSchedulesRepositoryImpl(remote);
|
||||
});
|
||||
@@ -0,0 +1,14 @@
|
||||
import 'package:device_management/src/features/app_usage_schedules/presentation/app_usage_schedules_screen.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
class AppUsageSchedulesBuilder {
|
||||
const AppUsageSchedulesBuilder();
|
||||
|
||||
Page<void> buildPage(BuildContext context, GoRouterState state) {
|
||||
return MaterialPage<void>(
|
||||
key: state.pageKey,
|
||||
child: const AppUsageSchedulesScreen(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,281 @@
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:device_management/src/core/domain/entities/app_usage_schedule_entity.dart';
|
||||
import 'package:device_management/src/features/app_usage_schedules/presentation/providers/app_usage_schedules_controller.dart';
|
||||
import 'package:device_management/src/features/app_usage_schedules/presentation/providers/app_usage_schedules_editor_provider.dart';
|
||||
import 'package:device_management/src/features/app_usage_schedules/presentation/providers/app_usage_schedules_provider.dart';
|
||||
import 'package:device_management/src/features/app_usage_schedules/presentation/widgets/edit_schedule_period_sheet.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:legacy_device_state/legacy_device_state.dart';
|
||||
import 'package:legacy_theme/legacy_theme.dart';
|
||||
import 'package:legacy_ui/legacy_ui.dart';
|
||||
import 'package:sf_localizations/sf_localizations.dart';
|
||||
import 'package:sf_shared/sf_shared.dart';
|
||||
import 'package:utils/utils.dart';
|
||||
|
||||
class AppUsageSchedulesScreen extends ConsumerWidget {
|
||||
const AppUsageSchedulesScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final device = ref.watch(selectedDeviceProvider).value;
|
||||
final primaryColor = context.sfColors.legacyPrimary;
|
||||
final maxPeriods =
|
||||
device?.capabilities?.appUsageSchedules?.maxPeriods ?? 3;
|
||||
|
||||
ref.listen(appUsageSchedulesControllerProvider, (prev, next) async {
|
||||
if (prev == null || !prev.isLoading || next.isLoading) return;
|
||||
if (next.hasError) {
|
||||
await showErrorDialog(context, I18n.errorAppUsageSchedules);
|
||||
return;
|
||||
}
|
||||
await showSuccessDialog(context, I18n.appUsageSchedulesSaved);
|
||||
});
|
||||
|
||||
if (device == null) {
|
||||
return LegacyPageLayout(
|
||||
title: context.translate(I18n.appUsageSchedulesTitle),
|
||||
body: const LegacyLoadingIndicator(),
|
||||
);
|
||||
}
|
||||
|
||||
final schedulesAsync = ref.watch(
|
||||
appUsageSchedulesProvider(device.identificator),
|
||||
);
|
||||
final pendingPeriods = ref.watch(appUsageSchedulesEditorProvider);
|
||||
final isSaving = ref.watch(
|
||||
appUsageSchedulesControllerProvider.select((s) => s.isLoading),
|
||||
);
|
||||
|
||||
return schedulesAsync.when(
|
||||
loading: () => LegacyPageLayout(
|
||||
title: context.translate(I18n.appUsageSchedulesTitle),
|
||||
body: const LegacyLoadingIndicator(),
|
||||
),
|
||||
error: (_, __) => LegacyPageLayout(
|
||||
title: context.translate(I18n.appUsageSchedulesTitle),
|
||||
body: Center(child: Text(context.translate(I18n.errorGeneric))),
|
||||
),
|
||||
data: (fetchedPeriods) {
|
||||
final periods = pendingPeriods ?? fetchedPeriods;
|
||||
final canAdd = periods.length < maxPeriods;
|
||||
|
||||
return LegacyPageLayout(
|
||||
title: context.translate(I18n.appUsageSchedulesTitle),
|
||||
body: SingleChildScrollView(
|
||||
padding: SizeUtils.getByScreen(
|
||||
small: const EdgeInsets.symmetric(horizontal: 22, vertical: 10),
|
||||
big: const EdgeInsets.symmetric(horizontal: 21, vertical: 8),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
for (int i = 0; i < periods.length; i++) ...[
|
||||
_PeriodTile(
|
||||
index: i,
|
||||
period: periods[i],
|
||||
onTap: () async {
|
||||
final result = await showEditSchedulePeriodSheet(
|
||||
context,
|
||||
initial: periods[i],
|
||||
);
|
||||
if (result == null) return;
|
||||
final editor = ref.read(
|
||||
appUsageSchedulesEditorProvider.notifier,
|
||||
);
|
||||
if (pendingPeriods == null) {
|
||||
editor.init(fetchedPeriods);
|
||||
}
|
||||
editor.replace(i, result);
|
||||
},
|
||||
onToggle: (enabled) {
|
||||
final editor = ref.read(
|
||||
appUsageSchedulesEditorProvider.notifier,
|
||||
);
|
||||
if (pendingPeriods == null) {
|
||||
editor.init(fetchedPeriods);
|
||||
}
|
||||
editor.replace(
|
||||
i,
|
||||
periods[i].copyWith(isPeriodEnabled: enabled),
|
||||
);
|
||||
},
|
||||
),
|
||||
if (i < periods.length - 1)
|
||||
SizedBox(
|
||||
height: SizeUtils.getByScreen(small: 8, big: 6),
|
||||
),
|
||||
],
|
||||
if (canAdd) ...[
|
||||
SizedBox(
|
||||
height: SizeUtils.getByScreen(small: 8, big: 6),
|
||||
),
|
||||
_AddPeriodTile(
|
||||
onTap: () async {
|
||||
if (!await guardDeviceCommand(context, ref)) return;
|
||||
if (!context.mounted) return;
|
||||
final result = await showEditSchedulePeriodSheet(context);
|
||||
if (result == null) return;
|
||||
final editor = ref.read(
|
||||
appUsageSchedulesEditorProvider.notifier,
|
||||
);
|
||||
if (pendingPeriods == null) {
|
||||
editor.init(fetchedPeriods);
|
||||
}
|
||||
editor.add(result);
|
||||
},
|
||||
),
|
||||
],
|
||||
SizedBox(
|
||||
height: SizeUtils.getByScreen(small: 24, big: 20),
|
||||
),
|
||||
Text(
|
||||
context.translate(I18n.appUsageSchedulesHint),
|
||||
style: TextStyle(
|
||||
fontSize: SizeUtils.getByScreen(small: 13, big: 14),
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
footer: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 10),
|
||||
child: isSaving
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
: PrimaryButton(
|
||||
onPressed: () async {
|
||||
if (!await guardDeviceCommand(context, ref)) return;
|
||||
if (!context.mounted) return;
|
||||
await ref
|
||||
.read(
|
||||
appUsageSchedulesControllerProvider.notifier,
|
||||
)
|
||||
.save(
|
||||
identificator: device.identificator,
|
||||
periods: periods,
|
||||
);
|
||||
},
|
||||
text: context.translate(I18n.save),
|
||||
color: primaryColor,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _PeriodTile extends StatelessWidget {
|
||||
final int index;
|
||||
final AppUsageSchedulePeriodEntity period;
|
||||
final VoidCallback onTap;
|
||||
final ValueChanged<bool> onToggle;
|
||||
|
||||
const _PeriodTile({
|
||||
required this.index,
|
||||
required this.period,
|
||||
required this.onTap,
|
||||
required this.onToggle,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.surfaceContainer,
|
||||
borderRadius: BorderRadius.circular(14),
|
||||
),
|
||||
child: InkWell(
|
||||
onTap: onTap,
|
||||
borderRadius: BorderRadius.circular(14),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: SizeUtils.getByScreen(small: 16, big: 14),
|
||||
vertical: SizeUtils.getByScreen(small: 12, big: 10),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'${context.translate(I18n.appUsageSchedulesPeriodLabel)} ${index + 1}',
|
||||
style: TextStyle(
|
||||
fontSize: SizeUtils.getByScreen(small: 15, big: 16),
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
'${period.periodStart} - ${period.periodEnd}',
|
||||
style: TextStyle(
|
||||
fontSize: SizeUtils.getByScreen(small: 13, big: 14),
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Switch.adaptive(
|
||||
value: period.isPeriodEnabled,
|
||||
onChanged: onToggle,
|
||||
activeTrackColor: context.sfColors.legacyPrimary,
|
||||
),
|
||||
Icon(
|
||||
Icons.chevron_right,
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
size: 20,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _AddPeriodTile extends StatelessWidget {
|
||||
final VoidCallback onTap;
|
||||
|
||||
const _AddPeriodTile({required this.onTap});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.surfaceContainer,
|
||||
borderRadius: BorderRadius.circular(14),
|
||||
),
|
||||
child: InkWell(
|
||||
onTap: onTap,
|
||||
borderRadius: BorderRadius.circular(14),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: SizeUtils.getByScreen(small: 16, big: 14),
|
||||
vertical: SizeUtils.getByScreen(small: 14, big: 12),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
context.translate(I18n.appUsageSchedulesAddPeriod),
|
||||
style: TextStyle(
|
||||
fontSize: SizeUtils.getByScreen(small: 15, big: 16),
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
Icon(
|
||||
Icons.chevron_right,
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
size: 20,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:device_management/src/core/domain/entities/app_usage_schedule_entity.dart';
|
||||
import 'package:device_management/src/core/providers/app_usage_schedules_repository_provider.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
|
||||
part 'app_usage_schedules_controller.g.dart';
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
class AppUsageSchedulesController extends _$AppUsageSchedulesController {
|
||||
@override
|
||||
FutureOr<void> build() {}
|
||||
|
||||
Future<void> save({
|
||||
required String identificator,
|
||||
required List<AppUsageSchedulePeriodEntity> periods,
|
||||
}) async {
|
||||
state = const AsyncLoading();
|
||||
state = await AsyncValue.guard(() async {
|
||||
await ref.read(appUsageSchedulesRepositoryProvider).upsertSchedules(
|
||||
identificator: identificator,
|
||||
periods: periods,
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'app_usage_schedules_controller.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint, type=warning
|
||||
|
||||
@ProviderFor(AppUsageSchedulesController)
|
||||
const appUsageSchedulesControllerProvider =
|
||||
AppUsageSchedulesControllerProvider._();
|
||||
|
||||
final class AppUsageSchedulesControllerProvider
|
||||
extends $AsyncNotifierProvider<AppUsageSchedulesController, void> {
|
||||
const AppUsageSchedulesControllerProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
retry: null,
|
||||
name: r'appUsageSchedulesControllerProvider',
|
||||
isAutoDispose: false,
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@override
|
||||
String debugGetCreateSourceHash() => _$appUsageSchedulesControllerHash();
|
||||
|
||||
@$internal
|
||||
@override
|
||||
AppUsageSchedulesController create() => AppUsageSchedulesController();
|
||||
}
|
||||
|
||||
String _$appUsageSchedulesControllerHash() =>
|
||||
r'c46ea8d94d602b29c5b76774e0bb1d0e5d4479ce';
|
||||
|
||||
abstract class _$AppUsageSchedulesController extends $AsyncNotifier<void> {
|
||||
FutureOr<void> build();
|
||||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
build();
|
||||
final ref = this.ref as $Ref<AsyncValue<void>, void>;
|
||||
final element =
|
||||
ref.element
|
||||
as $ClassProviderElement<
|
||||
AnyNotifier<AsyncValue<void>, void>,
|
||||
AsyncValue<void>,
|
||||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import 'package:device_management/src/core/domain/entities/app_usage_schedule_entity.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
|
||||
part 'app_usage_schedules_editor_provider.g.dart';
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
class AppUsageSchedulesEditor extends _$AppUsageSchedulesEditor {
|
||||
@override
|
||||
List<AppUsageSchedulePeriodEntity>? build() => null;
|
||||
|
||||
void init(List<AppUsageSchedulePeriodEntity> periods) {
|
||||
state = List.of(periods);
|
||||
}
|
||||
|
||||
void add(AppUsageSchedulePeriodEntity period) {
|
||||
state = [...?state, period];
|
||||
}
|
||||
|
||||
void replace(int index, AppUsageSchedulePeriodEntity period) {
|
||||
if (state == null || index >= state!.length) return;
|
||||
final updated = [...state!];
|
||||
updated[index] = period;
|
||||
state = updated;
|
||||
}
|
||||
|
||||
void remove(int index) {
|
||||
if (state == null || index >= state!.length) return;
|
||||
final updated = [...state!]..removeAt(index);
|
||||
state = updated;
|
||||
}
|
||||
|
||||
void clear() => state = null;
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'app_usage_schedules_editor_provider.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint, type=warning
|
||||
|
||||
@ProviderFor(AppUsageSchedulesEditor)
|
||||
const appUsageSchedulesEditorProvider = AppUsageSchedulesEditorProvider._();
|
||||
|
||||
final class AppUsageSchedulesEditorProvider
|
||||
extends
|
||||
$NotifierProvider<
|
||||
AppUsageSchedulesEditor,
|
||||
List<AppUsageSchedulePeriodEntity>?
|
||||
> {
|
||||
const AppUsageSchedulesEditorProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
retry: null,
|
||||
name: r'appUsageSchedulesEditorProvider',
|
||||
isAutoDispose: false,
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@override
|
||||
String debugGetCreateSourceHash() => _$appUsageSchedulesEditorHash();
|
||||
|
||||
@$internal
|
||||
@override
|
||||
AppUsageSchedulesEditor create() => AppUsageSchedulesEditor();
|
||||
|
||||
/// {@macro riverpod.override_with_value}
|
||||
Override overrideWithValue(List<AppUsageSchedulePeriodEntity>? value) {
|
||||
return $ProviderOverride(
|
||||
origin: this,
|
||||
providerOverride: $SyncValueProvider<List<AppUsageSchedulePeriodEntity>?>(
|
||||
value,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
String _$appUsageSchedulesEditorHash() =>
|
||||
r'2320c17df5db988aff843ce69e9dc5a352e70cfe';
|
||||
|
||||
abstract class _$AppUsageSchedulesEditor
|
||||
extends $Notifier<List<AppUsageSchedulePeriodEntity>?> {
|
||||
List<AppUsageSchedulePeriodEntity>? build();
|
||||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build();
|
||||
final ref =
|
||||
this.ref
|
||||
as $Ref<
|
||||
List<AppUsageSchedulePeriodEntity>?,
|
||||
List<AppUsageSchedulePeriodEntity>?
|
||||
>;
|
||||
final element =
|
||||
ref.element
|
||||
as $ClassProviderElement<
|
||||
AnyNotifier<
|
||||
List<AppUsageSchedulePeriodEntity>?,
|
||||
List<AppUsageSchedulePeriodEntity>?
|
||||
>,
|
||||
List<AppUsageSchedulePeriodEntity>?,
|
||||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import 'package:device_management/src/core/domain/entities/app_usage_schedule_entity.dart';
|
||||
import 'package:device_management/src/core/providers/app_usage_schedules_repository_provider.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
|
||||
part 'app_usage_schedules_provider.g.dart';
|
||||
|
||||
@riverpod
|
||||
Future<List<AppUsageSchedulePeriodEntity>> appUsageSchedules(
|
||||
Ref ref,
|
||||
String identificator,
|
||||
) async {
|
||||
final all = await ref
|
||||
.read(appUsageSchedulesRepositoryProvider)
|
||||
.getSchedules(identificator: identificator);
|
||||
return all
|
||||
.where(
|
||||
(p) =>
|
||||
p.isPeriodEnabled ||
|
||||
p.periodStart != '00:00' ||
|
||||
p.periodEnd != '00:00',
|
||||
)
|
||||
.toList();
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'app_usage_schedules_provider.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint, type=warning
|
||||
|
||||
@ProviderFor(appUsageSchedules)
|
||||
const appUsageSchedulesProvider = AppUsageSchedulesFamily._();
|
||||
|
||||
final class AppUsageSchedulesProvider
|
||||
extends
|
||||
$FunctionalProvider<
|
||||
AsyncValue<List<AppUsageSchedulePeriodEntity>>,
|
||||
List<AppUsageSchedulePeriodEntity>,
|
||||
FutureOr<List<AppUsageSchedulePeriodEntity>>
|
||||
>
|
||||
with
|
||||
$FutureModifier<List<AppUsageSchedulePeriodEntity>>,
|
||||
$FutureProvider<List<AppUsageSchedulePeriodEntity>> {
|
||||
const AppUsageSchedulesProvider._({
|
||||
required AppUsageSchedulesFamily super.from,
|
||||
required String super.argument,
|
||||
}) : super(
|
||||
retry: null,
|
||||
name: r'appUsageSchedulesProvider',
|
||||
isAutoDispose: true,
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@override
|
||||
String debugGetCreateSourceHash() => _$appUsageSchedulesHash();
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return r'appUsageSchedulesProvider'
|
||||
''
|
||||
'($argument)';
|
||||
}
|
||||
|
||||
@$internal
|
||||
@override
|
||||
$FutureProviderElement<List<AppUsageSchedulePeriodEntity>> $createElement(
|
||||
$ProviderPointer pointer,
|
||||
) => $FutureProviderElement(pointer);
|
||||
|
||||
@override
|
||||
FutureOr<List<AppUsageSchedulePeriodEntity>> create(Ref ref) {
|
||||
final argument = this.argument as String;
|
||||
return appUsageSchedules(ref, argument);
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return other is AppUsageSchedulesProvider && other.argument == argument;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return argument.hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
String _$appUsageSchedulesHash() => r'08505b0c1703239eb61267e562c8636e7959d0ad';
|
||||
|
||||
final class AppUsageSchedulesFamily extends $Family
|
||||
with
|
||||
$FunctionalFamilyOverride<
|
||||
FutureOr<List<AppUsageSchedulePeriodEntity>>,
|
||||
String
|
||||
> {
|
||||
const AppUsageSchedulesFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'appUsageSchedulesProvider',
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
isAutoDispose: true,
|
||||
);
|
||||
|
||||
AppUsageSchedulesProvider call(String identificator) =>
|
||||
AppUsageSchedulesProvider._(argument: identificator, from: this);
|
||||
|
||||
@override
|
||||
String toString() => r'appUsageSchedulesProvider';
|
||||
}
|
||||
@@ -0,0 +1,211 @@
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:device_management/src/core/domain/entities/app_usage_schedule_entity.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:legacy_theme/legacy_theme.dart';
|
||||
import 'package:sf_localizations/sf_localizations.dart';
|
||||
import 'package:utils/utils.dart';
|
||||
|
||||
Future<AppUsageSchedulePeriodEntity?> showEditSchedulePeriodSheet(
|
||||
BuildContext context, {
|
||||
AppUsageSchedulePeriodEntity? initial,
|
||||
}) {
|
||||
return showModalBottomSheet<AppUsageSchedulePeriodEntity>(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
backgroundColor: Colors.transparent,
|
||||
builder: (_) => _EditSchedulePeriodSheet(initial: initial),
|
||||
);
|
||||
}
|
||||
|
||||
class _EditSchedulePeriodSheet extends StatefulWidget {
|
||||
final AppUsageSchedulePeriodEntity? initial;
|
||||
|
||||
const _EditSchedulePeriodSheet({this.initial});
|
||||
|
||||
@override
|
||||
State<_EditSchedulePeriodSheet> createState() =>
|
||||
_EditSchedulePeriodSheetState();
|
||||
}
|
||||
|
||||
class _EditSchedulePeriodSheetState extends State<_EditSchedulePeriodSheet> {
|
||||
late TimeOfDay _start;
|
||||
late TimeOfDay _end;
|
||||
late bool _enabled;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_start = _parse(widget.initial?.periodStart ?? '08:00');
|
||||
_end = _parse(widget.initial?.periodEnd ?? '10:00');
|
||||
_enabled = widget.initial?.isPeriodEnabled ?? true;
|
||||
}
|
||||
|
||||
TimeOfDay _parse(String hhmm) {
|
||||
final parts = hhmm.split(':');
|
||||
return TimeOfDay(
|
||||
hour: int.tryParse(parts[0]) ?? 0,
|
||||
minute: int.tryParse(parts[1]) ?? 0,
|
||||
);
|
||||
}
|
||||
|
||||
String _format(TimeOfDay t) =>
|
||||
'${t.hour.toString().padLeft(2, '0')}:${t.minute.toString().padLeft(2, '0')}';
|
||||
|
||||
Future<void> _pickTime({required bool isStart}) async {
|
||||
final picked = await showTimePicker(
|
||||
context: context,
|
||||
initialTime: isStart ? _start : _end,
|
||||
);
|
||||
if (picked == null) return;
|
||||
setState(() {
|
||||
if (isStart) {
|
||||
_start = picked;
|
||||
} else {
|
||||
_end = picked;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void _submit() {
|
||||
Navigator.of(context).pop(
|
||||
AppUsageSchedulePeriodEntity(
|
||||
periodStart: _format(_start),
|
||||
periodEnd: _format(_end),
|
||||
isPeriodEnabled: _enabled,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final primaryColor = context.sfColors.legacyPrimary;
|
||||
final bottomInset = MediaQuery.of(context).viewInsets.bottom;
|
||||
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
borderRadius: const BorderRadius.vertical(top: Radius.circular(24)),
|
||||
),
|
||||
padding: EdgeInsets.fromLTRB(
|
||||
24,
|
||||
16,
|
||||
24,
|
||||
24 + bottomInset + MediaQuery.of(context).padding.bottom,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Container(
|
||||
height: 4,
|
||||
width: 48,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey.withValues(alpha: 0.35),
|
||||
borderRadius: BorderRadius.circular(999),
|
||||
),
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 20, big: 18)),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: _TimePickerButton(
|
||||
label: context.translate(
|
||||
I18n.appUsageSchedulesPeriodStart,
|
||||
),
|
||||
value: _format(_start),
|
||||
onTap: () => _pickTime(isStart: true),
|
||||
color: primaryColor,
|
||||
),
|
||||
),
|
||||
SizedBox(width: SizeUtils.getByScreen(small: 16, big: 14)),
|
||||
Expanded(
|
||||
child: _TimePickerButton(
|
||||
label: context.translate(
|
||||
I18n.appUsageSchedulesPeriodEnd,
|
||||
),
|
||||
value: _format(_end),
|
||||
onTap: () => _pickTime(isStart: false),
|
||||
color: primaryColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 14)),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
context.translate(I18n.enabled),
|
||||
style: TextStyle(
|
||||
fontSize: SizeUtils.getByScreen(small: 15, big: 16),
|
||||
),
|
||||
),
|
||||
Switch.adaptive(
|
||||
value: _enabled,
|
||||
onChanged: (v) => setState(() => _enabled = v),
|
||||
activeTrackColor: primaryColor,
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 14)),
|
||||
PrimaryButton(
|
||||
onPressed: _submit,
|
||||
text: context.translate(I18n.save),
|
||||
color: primaryColor,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _TimePickerButton extends StatelessWidget {
|
||||
final String label;
|
||||
final String value;
|
||||
final VoidCallback onTap;
|
||||
final Color color;
|
||||
|
||||
const _TimePickerButton({
|
||||
required this.label,
|
||||
required this.value,
|
||||
required this.onTap,
|
||||
required this.color,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: onTap,
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: SizeUtils.getByScreen(small: 14, big: 12),
|
||||
vertical: SizeUtils.getByScreen(small: 14, big: 12),
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: color.withValues(alpha: 0.3)),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
value,
|
||||
style: TextStyle(
|
||||
fontSize: 22,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: color,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user