feat(device-management): add installed apps enable/disable feature
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
import 'package:device_management/src/core/data/models/installed_apps_response_dto.dart';
|
||||
|
||||
abstract class InstalledAppsRemoteDatasource {
|
||||
Future<InstalledAppsResponseDto> getInstalledApps({
|
||||
required String identificator,
|
||||
});
|
||||
|
||||
Future<InstalledAppsResponseDto> updateInstalledApps({
|
||||
required String identificator,
|
||||
required List<Map<String, dynamic>> apps,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
import 'package:device_management/src/core/data/datasources/installed_apps_remote_datasource.dart';
|
||||
import 'package:device_management/src/core/data/models/installed_apps_response_dto.dart';
|
||||
import 'package:sf_infrastructure/sf_infrastructure.dart';
|
||||
|
||||
class InstalledAppsRemoteDatasourceImpl implements InstalledAppsRemoteDatasource {
|
||||
InstalledAppsRemoteDatasourceImpl(this._repository);
|
||||
|
||||
final SaveFamilyRepository _repository;
|
||||
|
||||
@override
|
||||
Future<InstalledAppsResponseDto> getInstalledApps({
|
||||
required String identificator,
|
||||
}) async {
|
||||
final response = await safeCall(
|
||||
() => _repository.get<Map<String, dynamic>>(
|
||||
'/devices/identificator/$identificator/installed-apps',
|
||||
),
|
||||
'Error getting installed apps',
|
||||
);
|
||||
|
||||
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 InstalledAppsResponseDto.fromJson(item);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<InstalledAppsResponseDto> updateInstalledApps({
|
||||
required String identificator,
|
||||
required List<Map<String, dynamic>> apps,
|
||||
}) async {
|
||||
final response = await safeCall(
|
||||
() => _repository.put<Map<String, dynamic>>(
|
||||
'/devices/identificator/$identificator/installed-apps',
|
||||
body: <String, dynamic>{'apps': apps},
|
||||
),
|
||||
'Error updating installed apps',
|
||||
);
|
||||
|
||||
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 InstalledAppsResponseDto.fromJson(item);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
import 'package:device_management/src/core/domain/entities/installed_app_entity.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'installed_apps_response_dto.freezed.dart';
|
||||
part 'installed_apps_response_dto.g.dart';
|
||||
|
||||
@freezed
|
||||
abstract class InstalledAppsResponseDto with _$InstalledAppsResponseDto {
|
||||
const factory InstalledAppsResponseDto({
|
||||
required String id,
|
||||
required String deviceIdentificator,
|
||||
required List<InstalledAppItemDto> apps,
|
||||
required int createdAt,
|
||||
int? updatedAt,
|
||||
}) = _InstalledAppsResponseDto;
|
||||
|
||||
factory InstalledAppsResponseDto.fromJson(Map<String, dynamic> json) =>
|
||||
_$InstalledAppsResponseDtoFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class InstalledAppItemDto with _$InstalledAppItemDto {
|
||||
const factory InstalledAppItemDto({
|
||||
required String appUid,
|
||||
required String appName,
|
||||
required bool isEnabled,
|
||||
}) = _InstalledAppItemDto;
|
||||
|
||||
factory InstalledAppItemDto.fromJson(Map<String, dynamic> json) =>
|
||||
_$InstalledAppItemDtoFromJson(json);
|
||||
}
|
||||
|
||||
extension InstalledAppsResponseDtoX on InstalledAppsResponseDto {
|
||||
List<InstalledAppEntity> toEntities() {
|
||||
return apps
|
||||
.map(
|
||||
(a) => InstalledAppEntity(
|
||||
appUid: a.appUid,
|
||||
appName: a.appName,
|
||||
isEnabled: a.isEnabled,
|
||||
),
|
||||
)
|
||||
.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 'installed_apps_response_dto.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
|
||||
/// @nodoc
|
||||
mixin _$InstalledAppsResponseDto {
|
||||
|
||||
String get id; String get deviceIdentificator; List<InstalledAppItemDto> get apps; int get createdAt; int? get updatedAt;
|
||||
/// Create a copy of InstalledAppsResponseDto
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$InstalledAppsResponseDtoCopyWith<InstalledAppsResponseDto> get copyWith => _$InstalledAppsResponseDtoCopyWithImpl<InstalledAppsResponseDto>(this as InstalledAppsResponseDto, _$identity);
|
||||
|
||||
/// Serializes this InstalledAppsResponseDto to a JSON map.
|
||||
Map<String, dynamic> toJson();
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is InstalledAppsResponseDto&&(identical(other.id, id) || other.id == id)&&(identical(other.deviceIdentificator, deviceIdentificator) || other.deviceIdentificator == deviceIdentificator)&&const DeepCollectionEquality().equals(other.apps, apps)&&(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(apps),createdAt,updatedAt);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'InstalledAppsResponseDto(id: $id, deviceIdentificator: $deviceIdentificator, apps: $apps, createdAt: $createdAt, updatedAt: $updatedAt)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $InstalledAppsResponseDtoCopyWith<$Res> {
|
||||
factory $InstalledAppsResponseDtoCopyWith(InstalledAppsResponseDto value, $Res Function(InstalledAppsResponseDto) _then) = _$InstalledAppsResponseDtoCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String id, String deviceIdentificator, List<InstalledAppItemDto> apps, int createdAt, int? updatedAt
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$InstalledAppsResponseDtoCopyWithImpl<$Res>
|
||||
implements $InstalledAppsResponseDtoCopyWith<$Res> {
|
||||
_$InstalledAppsResponseDtoCopyWithImpl(this._self, this._then);
|
||||
|
||||
final InstalledAppsResponseDto _self;
|
||||
final $Res Function(InstalledAppsResponseDto) _then;
|
||||
|
||||
/// Create a copy of InstalledAppsResponseDto
|
||||
/// 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? apps = 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,apps: null == apps ? _self.apps : apps // ignore: cast_nullable_to_non_nullable
|
||||
as List<InstalledAppItemDto>,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 [InstalledAppsResponseDto].
|
||||
extension InstalledAppsResponseDtoPatterns on InstalledAppsResponseDto {
|
||||
/// 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( _InstalledAppsResponseDto value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _InstalledAppsResponseDto() 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( _InstalledAppsResponseDto value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _InstalledAppsResponseDto():
|
||||
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( _InstalledAppsResponseDto value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _InstalledAppsResponseDto() 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<InstalledAppItemDto> apps, int createdAt, int? updatedAt)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _InstalledAppsResponseDto() when $default != null:
|
||||
return $default(_that.id,_that.deviceIdentificator,_that.apps,_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<InstalledAppItemDto> apps, int createdAt, int? updatedAt) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _InstalledAppsResponseDto():
|
||||
return $default(_that.id,_that.deviceIdentificator,_that.apps,_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<InstalledAppItemDto> apps, int createdAt, int? updatedAt)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _InstalledAppsResponseDto() when $default != null:
|
||||
return $default(_that.id,_that.deviceIdentificator,_that.apps,_that.createdAt,_that.updatedAt);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
|
||||
class _InstalledAppsResponseDto implements InstalledAppsResponseDto {
|
||||
const _InstalledAppsResponseDto({required this.id, required this.deviceIdentificator, required final List<InstalledAppItemDto> apps, required this.createdAt, this.updatedAt}): _apps = apps;
|
||||
factory _InstalledAppsResponseDto.fromJson(Map<String, dynamic> json) => _$InstalledAppsResponseDtoFromJson(json);
|
||||
|
||||
@override final String id;
|
||||
@override final String deviceIdentificator;
|
||||
final List<InstalledAppItemDto> _apps;
|
||||
@override List<InstalledAppItemDto> get apps {
|
||||
if (_apps is EqualUnmodifiableListView) return _apps;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_apps);
|
||||
}
|
||||
|
||||
@override final int createdAt;
|
||||
@override final int? updatedAt;
|
||||
|
||||
/// Create a copy of InstalledAppsResponseDto
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$InstalledAppsResponseDtoCopyWith<_InstalledAppsResponseDto> get copyWith => __$InstalledAppsResponseDtoCopyWithImpl<_InstalledAppsResponseDto>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$InstalledAppsResponseDtoToJson(this, );
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _InstalledAppsResponseDto&&(identical(other.id, id) || other.id == id)&&(identical(other.deviceIdentificator, deviceIdentificator) || other.deviceIdentificator == deviceIdentificator)&&const DeepCollectionEquality().equals(other._apps, _apps)&&(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(_apps),createdAt,updatedAt);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'InstalledAppsResponseDto(id: $id, deviceIdentificator: $deviceIdentificator, apps: $apps, createdAt: $createdAt, updatedAt: $updatedAt)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$InstalledAppsResponseDtoCopyWith<$Res> implements $InstalledAppsResponseDtoCopyWith<$Res> {
|
||||
factory _$InstalledAppsResponseDtoCopyWith(_InstalledAppsResponseDto value, $Res Function(_InstalledAppsResponseDto) _then) = __$InstalledAppsResponseDtoCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String id, String deviceIdentificator, List<InstalledAppItemDto> apps, int createdAt, int? updatedAt
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$InstalledAppsResponseDtoCopyWithImpl<$Res>
|
||||
implements _$InstalledAppsResponseDtoCopyWith<$Res> {
|
||||
__$InstalledAppsResponseDtoCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _InstalledAppsResponseDto _self;
|
||||
final $Res Function(_InstalledAppsResponseDto) _then;
|
||||
|
||||
/// Create a copy of InstalledAppsResponseDto
|
||||
/// 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? apps = null,Object? createdAt = null,Object? updatedAt = freezed,}) {
|
||||
return _then(_InstalledAppsResponseDto(
|
||||
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,apps: null == apps ? _self._apps : apps // ignore: cast_nullable_to_non_nullable
|
||||
as List<InstalledAppItemDto>,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 _$InstalledAppItemDto {
|
||||
|
||||
String get appUid; String get appName; bool get isEnabled;
|
||||
/// Create a copy of InstalledAppItemDto
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$InstalledAppItemDtoCopyWith<InstalledAppItemDto> get copyWith => _$InstalledAppItemDtoCopyWithImpl<InstalledAppItemDto>(this as InstalledAppItemDto, _$identity);
|
||||
|
||||
/// Serializes this InstalledAppItemDto to a JSON map.
|
||||
Map<String, dynamic> toJson();
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is InstalledAppItemDto&&(identical(other.appUid, appUid) || other.appUid == appUid)&&(identical(other.appName, appName) || other.appName == appName)&&(identical(other.isEnabled, isEnabled) || other.isEnabled == isEnabled));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,appUid,appName,isEnabled);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'InstalledAppItemDto(appUid: $appUid, appName: $appName, isEnabled: $isEnabled)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $InstalledAppItemDtoCopyWith<$Res> {
|
||||
factory $InstalledAppItemDtoCopyWith(InstalledAppItemDto value, $Res Function(InstalledAppItemDto) _then) = _$InstalledAppItemDtoCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String appUid, String appName, bool isEnabled
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$InstalledAppItemDtoCopyWithImpl<$Res>
|
||||
implements $InstalledAppItemDtoCopyWith<$Res> {
|
||||
_$InstalledAppItemDtoCopyWithImpl(this._self, this._then);
|
||||
|
||||
final InstalledAppItemDto _self;
|
||||
final $Res Function(InstalledAppItemDto) _then;
|
||||
|
||||
/// Create a copy of InstalledAppItemDto
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? appUid = null,Object? appName = null,Object? isEnabled = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
appUid: null == appUid ? _self.appUid : appUid // ignore: cast_nullable_to_non_nullable
|
||||
as String,appName: null == appName ? _self.appName : appName // ignore: cast_nullable_to_non_nullable
|
||||
as String,isEnabled: null == isEnabled ? _self.isEnabled : isEnabled // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [InstalledAppItemDto].
|
||||
extension InstalledAppItemDtoPatterns on InstalledAppItemDto {
|
||||
/// 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( _InstalledAppItemDto value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _InstalledAppItemDto() 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( _InstalledAppItemDto value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _InstalledAppItemDto():
|
||||
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( _InstalledAppItemDto value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _InstalledAppItemDto() 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 appUid, String appName, bool isEnabled)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _InstalledAppItemDto() when $default != null:
|
||||
return $default(_that.appUid,_that.appName,_that.isEnabled);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 appUid, String appName, bool isEnabled) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _InstalledAppItemDto():
|
||||
return $default(_that.appUid,_that.appName,_that.isEnabled);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 appUid, String appName, bool isEnabled)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _InstalledAppItemDto() when $default != null:
|
||||
return $default(_that.appUid,_that.appName,_that.isEnabled);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
|
||||
class _InstalledAppItemDto implements InstalledAppItemDto {
|
||||
const _InstalledAppItemDto({required this.appUid, required this.appName, required this.isEnabled});
|
||||
factory _InstalledAppItemDto.fromJson(Map<String, dynamic> json) => _$InstalledAppItemDtoFromJson(json);
|
||||
|
||||
@override final String appUid;
|
||||
@override final String appName;
|
||||
@override final bool isEnabled;
|
||||
|
||||
/// Create a copy of InstalledAppItemDto
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$InstalledAppItemDtoCopyWith<_InstalledAppItemDto> get copyWith => __$InstalledAppItemDtoCopyWithImpl<_InstalledAppItemDto>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$InstalledAppItemDtoToJson(this, );
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _InstalledAppItemDto&&(identical(other.appUid, appUid) || other.appUid == appUid)&&(identical(other.appName, appName) || other.appName == appName)&&(identical(other.isEnabled, isEnabled) || other.isEnabled == isEnabled));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,appUid,appName,isEnabled);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'InstalledAppItemDto(appUid: $appUid, appName: $appName, isEnabled: $isEnabled)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$InstalledAppItemDtoCopyWith<$Res> implements $InstalledAppItemDtoCopyWith<$Res> {
|
||||
factory _$InstalledAppItemDtoCopyWith(_InstalledAppItemDto value, $Res Function(_InstalledAppItemDto) _then) = __$InstalledAppItemDtoCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String appUid, String appName, bool isEnabled
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$InstalledAppItemDtoCopyWithImpl<$Res>
|
||||
implements _$InstalledAppItemDtoCopyWith<$Res> {
|
||||
__$InstalledAppItemDtoCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _InstalledAppItemDto _self;
|
||||
final $Res Function(_InstalledAppItemDto) _then;
|
||||
|
||||
/// Create a copy of InstalledAppItemDto
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? appUid = null,Object? appName = null,Object? isEnabled = null,}) {
|
||||
return _then(_InstalledAppItemDto(
|
||||
appUid: null == appUid ? _self.appUid : appUid // ignore: cast_nullable_to_non_nullable
|
||||
as String,appName: null == appName ? _self.appName : appName // ignore: cast_nullable_to_non_nullable
|
||||
as String,isEnabled: null == isEnabled ? _self.isEnabled : isEnabled // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -0,0 +1,44 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'installed_apps_response_dto.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_InstalledAppsResponseDto _$InstalledAppsResponseDtoFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _InstalledAppsResponseDto(
|
||||
id: json['id'] as String,
|
||||
deviceIdentificator: json['deviceIdentificator'] as String,
|
||||
apps: (json['apps'] as List<dynamic>)
|
||||
.map((e) => InstalledAppItemDto.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
createdAt: (json['createdAt'] as num).toInt(),
|
||||
updatedAt: (json['updatedAt'] as num?)?.toInt(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$InstalledAppsResponseDtoToJson(
|
||||
_InstalledAppsResponseDto instance,
|
||||
) => <String, dynamic>{
|
||||
'id': instance.id,
|
||||
'deviceIdentificator': instance.deviceIdentificator,
|
||||
'apps': instance.apps,
|
||||
'createdAt': instance.createdAt,
|
||||
'updatedAt': instance.updatedAt,
|
||||
};
|
||||
|
||||
_InstalledAppItemDto _$InstalledAppItemDtoFromJson(Map<String, dynamic> json) =>
|
||||
_InstalledAppItemDto(
|
||||
appUid: json['appUid'] as String,
|
||||
appName: json['appName'] as String,
|
||||
isEnabled: json['isEnabled'] as bool,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$InstalledAppItemDtoToJson(
|
||||
_InstalledAppItemDto instance,
|
||||
) => <String, dynamic>{
|
||||
'appUid': instance.appUid,
|
||||
'appName': instance.appName,
|
||||
'isEnabled': instance.isEnabled,
|
||||
};
|
||||
@@ -0,0 +1,42 @@
|
||||
import 'package:device_management/src/core/data/datasources/installed_apps_remote_datasource.dart';
|
||||
import 'package:device_management/src/core/data/models/installed_apps_response_dto.dart';
|
||||
import 'package:device_management/src/core/domain/entities/installed_app_entity.dart';
|
||||
import 'package:device_management/src/core/domain/repositories/installed_apps_repository.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:sf_infrastructure/sf_infrastructure.dart';
|
||||
|
||||
class InstalledAppsRepositoryImpl implements InstalledAppsRepository {
|
||||
InstalledAppsRepositoryImpl(this._remote);
|
||||
|
||||
final InstalledAppsRemoteDatasource _remote;
|
||||
|
||||
@override
|
||||
Future<List<InstalledAppEntity>> getInstalledApps({
|
||||
required String identificator,
|
||||
}) async {
|
||||
try {
|
||||
final response = await _remote.getInstalledApps(
|
||||
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 installed apps');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<InstalledAppEntity>> updateInstalledApps({
|
||||
required String identificator,
|
||||
required List<Map<String, dynamic>> apps,
|
||||
}) async {
|
||||
final response = await _remote.updateInstalledApps(
|
||||
identificator: identificator,
|
||||
apps: apps,
|
||||
);
|
||||
return response.toEntities();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'installed_app_entity.freezed.dart';
|
||||
|
||||
@freezed
|
||||
abstract class InstalledAppEntity with _$InstalledAppEntity {
|
||||
const factory InstalledAppEntity({
|
||||
required String appUid,
|
||||
required String appName,
|
||||
required bool isEnabled,
|
||||
}) = _InstalledAppEntity;
|
||||
}
|
||||
@@ -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 'installed_app_entity.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$InstalledAppEntity {
|
||||
|
||||
String get appUid; String get appName; bool get isEnabled;
|
||||
/// Create a copy of InstalledAppEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$InstalledAppEntityCopyWith<InstalledAppEntity> get copyWith => _$InstalledAppEntityCopyWithImpl<InstalledAppEntity>(this as InstalledAppEntity, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is InstalledAppEntity&&(identical(other.appUid, appUid) || other.appUid == appUid)&&(identical(other.appName, appName) || other.appName == appName)&&(identical(other.isEnabled, isEnabled) || other.isEnabled == isEnabled));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,appUid,appName,isEnabled);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'InstalledAppEntity(appUid: $appUid, appName: $appName, isEnabled: $isEnabled)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $InstalledAppEntityCopyWith<$Res> {
|
||||
factory $InstalledAppEntityCopyWith(InstalledAppEntity value, $Res Function(InstalledAppEntity) _then) = _$InstalledAppEntityCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String appUid, String appName, bool isEnabled
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$InstalledAppEntityCopyWithImpl<$Res>
|
||||
implements $InstalledAppEntityCopyWith<$Res> {
|
||||
_$InstalledAppEntityCopyWithImpl(this._self, this._then);
|
||||
|
||||
final InstalledAppEntity _self;
|
||||
final $Res Function(InstalledAppEntity) _then;
|
||||
|
||||
/// Create a copy of InstalledAppEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? appUid = null,Object? appName = null,Object? isEnabled = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
appUid: null == appUid ? _self.appUid : appUid // ignore: cast_nullable_to_non_nullable
|
||||
as String,appName: null == appName ? _self.appName : appName // ignore: cast_nullable_to_non_nullable
|
||||
as String,isEnabled: null == isEnabled ? _self.isEnabled : isEnabled // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [InstalledAppEntity].
|
||||
extension InstalledAppEntityPatterns on InstalledAppEntity {
|
||||
/// 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( _InstalledAppEntity value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _InstalledAppEntity() 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( _InstalledAppEntity value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _InstalledAppEntity():
|
||||
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( _InstalledAppEntity value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _InstalledAppEntity() 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 appUid, String appName, bool isEnabled)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _InstalledAppEntity() when $default != null:
|
||||
return $default(_that.appUid,_that.appName,_that.isEnabled);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 appUid, String appName, bool isEnabled) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _InstalledAppEntity():
|
||||
return $default(_that.appUid,_that.appName,_that.isEnabled);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 appUid, String appName, bool isEnabled)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _InstalledAppEntity() when $default != null:
|
||||
return $default(_that.appUid,_that.appName,_that.isEnabled);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _InstalledAppEntity implements InstalledAppEntity {
|
||||
const _InstalledAppEntity({required this.appUid, required this.appName, required this.isEnabled});
|
||||
|
||||
|
||||
@override final String appUid;
|
||||
@override final String appName;
|
||||
@override final bool isEnabled;
|
||||
|
||||
/// Create a copy of InstalledAppEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$InstalledAppEntityCopyWith<_InstalledAppEntity> get copyWith => __$InstalledAppEntityCopyWithImpl<_InstalledAppEntity>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _InstalledAppEntity&&(identical(other.appUid, appUid) || other.appUid == appUid)&&(identical(other.appName, appName) || other.appName == appName)&&(identical(other.isEnabled, isEnabled) || other.isEnabled == isEnabled));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,appUid,appName,isEnabled);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'InstalledAppEntity(appUid: $appUid, appName: $appName, isEnabled: $isEnabled)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$InstalledAppEntityCopyWith<$Res> implements $InstalledAppEntityCopyWith<$Res> {
|
||||
factory _$InstalledAppEntityCopyWith(_InstalledAppEntity value, $Res Function(_InstalledAppEntity) _then) = __$InstalledAppEntityCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String appUid, String appName, bool isEnabled
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$InstalledAppEntityCopyWithImpl<$Res>
|
||||
implements _$InstalledAppEntityCopyWith<$Res> {
|
||||
__$InstalledAppEntityCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _InstalledAppEntity _self;
|
||||
final $Res Function(_InstalledAppEntity) _then;
|
||||
|
||||
/// Create a copy of InstalledAppEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? appUid = null,Object? appName = null,Object? isEnabled = null,}) {
|
||||
return _then(_InstalledAppEntity(
|
||||
appUid: null == appUid ? _self.appUid : appUid // ignore: cast_nullable_to_non_nullable
|
||||
as String,appName: null == appName ? _self.appName : appName // ignore: cast_nullable_to_non_nullable
|
||||
as String,isEnabled: null == isEnabled ? _self.isEnabled : isEnabled // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -0,0 +1,12 @@
|
||||
import 'package:device_management/src/core/domain/entities/installed_app_entity.dart';
|
||||
|
||||
abstract class InstalledAppsRepository {
|
||||
Future<List<InstalledAppEntity>> getInstalledApps({
|
||||
required String identificator,
|
||||
});
|
||||
|
||||
Future<List<InstalledAppEntity>> updateInstalledApps({
|
||||
required String identificator,
|
||||
required List<Map<String, dynamic>> apps,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import 'package:device_management/src/core/data/datasources/installed_apps_remote_datasource_impl.dart';
|
||||
import 'package:device_management/src/core/data/repositories/installed_apps_repository_impl.dart';
|
||||
import 'package:device_management/src/core/domain/repositories/installed_apps_repository.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:sf_infrastructure/sf_infrastructure.dart';
|
||||
|
||||
final installedAppsRepositoryProvider = Provider<InstalledAppsRepository>((ref) {
|
||||
final remote = InstalledAppsRemoteDatasourceImpl(getIt<SaveFamilyRepository>());
|
||||
return InstalledAppsRepositoryImpl(remote);
|
||||
});
|
||||
@@ -0,0 +1,14 @@
|
||||
import 'package:device_management/src/features/installed_apps/presentation/installed_apps_screen.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
class InstalledAppsBuilder {
|
||||
const InstalledAppsBuilder();
|
||||
|
||||
Page<void> buildPage(BuildContext context, GoRouterState state) {
|
||||
return MaterialPage<void>(
|
||||
key: state.pageKey,
|
||||
child: const InstalledAppsScreen(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:device_management/src/core/domain/entities/installed_app_entity.dart';
|
||||
import 'package:device_management/src/features/installed_apps/presentation/providers/installed_apps_controller.dart';
|
||||
import 'package:device_management/src/features/installed_apps/presentation/providers/installed_apps_provider.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:navigation/navigation.dart';
|
||||
import 'package:sf_localizations/sf_localizations.dart';
|
||||
import 'package:sf_shared/sf_shared.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:utils/utils.dart';
|
||||
|
||||
class InstalledAppsScreen extends ConsumerWidget {
|
||||
const InstalledAppsScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final device = ref.watch(selectedDeviceProvider).value;
|
||||
final primaryColor = context.sfColors.legacyPrimary;
|
||||
|
||||
ref.listen(installedAppsControllerProvider, (prev, next) {
|
||||
next.showErrorOn(context);
|
||||
if (prev != null && prev.isLoading && !next.isLoading && !next.hasError) {
|
||||
showSuccessDialog(context, I18n.installedAppsUpdated);
|
||||
}
|
||||
});
|
||||
|
||||
if (device == null) {
|
||||
return LegacyPageLayout(
|
||||
title: context.translate(I18n.installedAppsTitle),
|
||||
body: const LegacyLoadingIndicator(),
|
||||
);
|
||||
}
|
||||
|
||||
final appsAsync = ref.watch(installedAppsProvider(device.identificator));
|
||||
final isUpdating = ref.watch(
|
||||
installedAppsControllerProvider.select((s) => s.isLoading),
|
||||
);
|
||||
|
||||
return LegacyPageLayout(
|
||||
title: context.translate(I18n.installedAppsTitle),
|
||||
showEdit: true,
|
||||
onEditChange: () {
|
||||
GetIt.I<NavigationContract>().pushTo(AppRoutes.appUsageSchedules);
|
||||
},
|
||||
body: appsAsync.when(
|
||||
loading: () => const LegacyLoadingIndicator(),
|
||||
error: (_, __) =>
|
||||
Center(child: Text(context.translate(I18n.errorGeneric))),
|
||||
data: (apps) {
|
||||
if (apps.isEmpty) {
|
||||
return Center(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.apps_outlined,
|
||||
color: primaryColor,
|
||||
size: SizeUtils.getByScreen(small: 80, big: 90),
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 20)),
|
||||
Text(
|
||||
context.translate(I18n.installedAppsEmpty),
|
||||
style: const TextStyle(color: Colors.grey, fontSize: 16),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return AbsorbPointer(
|
||||
absorbing: isUpdating,
|
||||
child: Opacity(
|
||||
opacity: isUpdating ? 0.5 : 1.0,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: SizeUtils.getByScreen(small: 24, big: 22),
|
||||
vertical: SizeUtils.getByScreen(small: 8, big: 6),
|
||||
),
|
||||
child: Text(
|
||||
context.translate(I18n.installedAppsSubtitle),
|
||||
style: TextStyle(
|
||||
fontSize: SizeUtils.getByScreen(small: 13, big: 14),
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: ListView.separated(
|
||||
padding: SizeUtils.getByScreen(
|
||||
small: const EdgeInsets.symmetric(
|
||||
horizontal: 22,
|
||||
vertical: 10,
|
||||
),
|
||||
big: const EdgeInsets.symmetric(
|
||||
horizontal: 21,
|
||||
vertical: 8,
|
||||
),
|
||||
),
|
||||
itemCount: apps.length,
|
||||
separatorBuilder: (_, __) => SizedBox(
|
||||
height: SizeUtils.getByScreen(small: 10, big: 8),
|
||||
),
|
||||
itemBuilder: (_, index) => _AppCard(
|
||||
app: apps[index],
|
||||
onToggle: (enabled) async {
|
||||
if (!await guardDeviceCommand(context, ref)) return;
|
||||
if (!context.mounted) return;
|
||||
ref
|
||||
.read(installedAppsControllerProvider.notifier)
|
||||
.toggleApp(
|
||||
identificator: device.identificator,
|
||||
appUid: apps[index].appUid,
|
||||
isEnabled: enabled,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _AppCard extends StatelessWidget {
|
||||
final InstalledAppEntity app;
|
||||
final ValueChanged<bool> onToggle;
|
||||
|
||||
const _AppCard({required this.app, required this.onToggle});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final primaryColor = context.sfColors.legacyPrimary;
|
||||
|
||||
return Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: SizeUtils.getByScreen(small: 16, big: 14),
|
||||
vertical: SizeUtils.getByScreen(small: 12, big: 10),
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.surfaceContainer,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(14)),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
app.appName,
|
||||
style: TextStyle(
|
||||
fontSize: SizeUtils.getByScreen(small: 15, big: 16),
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
Switch.adaptive(
|
||||
value: app.isEnabled,
|
||||
onChanged: onToggle,
|
||||
activeTrackColor: primaryColor,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:device_management/src/core/providers/installed_apps_repository_provider.dart';
|
||||
import 'package:device_management/src/features/installed_apps/presentation/providers/installed_apps_provider.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
|
||||
part 'installed_apps_controller.g.dart';
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
class InstalledAppsController extends _$InstalledAppsController {
|
||||
@override
|
||||
FutureOr<void> build() {}
|
||||
|
||||
Future<void> toggleApp({
|
||||
required String identificator,
|
||||
required String appUid,
|
||||
required bool isEnabled,
|
||||
}) async {
|
||||
state = const AsyncLoading();
|
||||
state = await AsyncValue.guard(() async {
|
||||
await ref.read(installedAppsRepositoryProvider).updateInstalledApps(
|
||||
identificator: identificator,
|
||||
apps: [
|
||||
{'appUid': appUid, 'isEnabled': isEnabled},
|
||||
],
|
||||
);
|
||||
ref.invalidate(installedAppsProvider(identificator));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'installed_apps_controller.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint, type=warning
|
||||
|
||||
@ProviderFor(InstalledAppsController)
|
||||
const installedAppsControllerProvider = InstalledAppsControllerProvider._();
|
||||
|
||||
final class InstalledAppsControllerProvider
|
||||
extends $AsyncNotifierProvider<InstalledAppsController, void> {
|
||||
const InstalledAppsControllerProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
retry: null,
|
||||
name: r'installedAppsControllerProvider',
|
||||
isAutoDispose: false,
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@override
|
||||
String debugGetCreateSourceHash() => _$installedAppsControllerHash();
|
||||
|
||||
@$internal
|
||||
@override
|
||||
InstalledAppsController create() => InstalledAppsController();
|
||||
}
|
||||
|
||||
String _$installedAppsControllerHash() =>
|
||||
r'00a01c2dea9e0acaca4f4b7212033381b59b1f7e';
|
||||
|
||||
abstract class _$InstalledAppsController 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,15 @@
|
||||
import 'package:device_management/src/core/domain/entities/installed_app_entity.dart';
|
||||
import 'package:device_management/src/core/providers/installed_apps_repository_provider.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
|
||||
part 'installed_apps_provider.g.dart';
|
||||
|
||||
@riverpod
|
||||
Future<List<InstalledAppEntity>> installedApps(
|
||||
Ref ref,
|
||||
String identificator,
|
||||
) async {
|
||||
return ref
|
||||
.read(installedAppsRepositoryProvider)
|
||||
.getInstalledApps(identificator: identificator);
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'installed_apps_provider.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint, type=warning
|
||||
|
||||
@ProviderFor(installedApps)
|
||||
const installedAppsProvider = InstalledAppsFamily._();
|
||||
|
||||
final class InstalledAppsProvider
|
||||
extends
|
||||
$FunctionalProvider<
|
||||
AsyncValue<List<InstalledAppEntity>>,
|
||||
List<InstalledAppEntity>,
|
||||
FutureOr<List<InstalledAppEntity>>
|
||||
>
|
||||
with
|
||||
$FutureModifier<List<InstalledAppEntity>>,
|
||||
$FutureProvider<List<InstalledAppEntity>> {
|
||||
const InstalledAppsProvider._({
|
||||
required InstalledAppsFamily super.from,
|
||||
required String super.argument,
|
||||
}) : super(
|
||||
retry: null,
|
||||
name: r'installedAppsProvider',
|
||||
isAutoDispose: true,
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@override
|
||||
String debugGetCreateSourceHash() => _$installedAppsHash();
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return r'installedAppsProvider'
|
||||
''
|
||||
'($argument)';
|
||||
}
|
||||
|
||||
@$internal
|
||||
@override
|
||||
$FutureProviderElement<List<InstalledAppEntity>> $createElement(
|
||||
$ProviderPointer pointer,
|
||||
) => $FutureProviderElement(pointer);
|
||||
|
||||
@override
|
||||
FutureOr<List<InstalledAppEntity>> create(Ref ref) {
|
||||
final argument = this.argument as String;
|
||||
return installedApps(ref, argument);
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return other is InstalledAppsProvider && other.argument == argument;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return argument.hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
String _$installedAppsHash() => r'4f79eec7a30099f6d01f7a22d1e921818a544a26';
|
||||
|
||||
final class InstalledAppsFamily extends $Family
|
||||
with $FunctionalFamilyOverride<FutureOr<List<InstalledAppEntity>>, String> {
|
||||
const InstalledAppsFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'installedAppsProvider',
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
isAutoDispose: true,
|
||||
);
|
||||
|
||||
InstalledAppsProvider call(String identificator) =>
|
||||
InstalledAppsProvider._(argument: identificator, from: this);
|
||||
|
||||
@override
|
||||
String toString() => r'installedAppsProvider';
|
||||
}
|
||||
Reference in New Issue
Block a user