feat(backups): Show the snapshot creation reason

pull/331/head
Inex Code 2023-09-09 10:22:43 +03:00
parent ef91ffaf2b
commit aac4b2773b
7 changed files with 293 additions and 2 deletions

View File

@ -220,7 +220,14 @@
"snapshot_modal_inplace_option_title": "Replace in place",
"snapshot_modal_inplace_option_description": "Less free space needed, but more risk. Replaces current data with the snapshot data during the download.",
"snapshot_modal_service_not_found": "This is a snapshot of a service you don't have on your server anymore. Usually this shouldn't happen, and we cannot do the automatic restore. You can still download the snapshot and restore it manually. Contact SelfPrivacy support if you need help.",
"restore_started": "Restore started, check the jobs list for the current status"
"restore_started": "Restore started, check the jobs list for the current status",
"snapshot_reason_title": "Creation reason",
"snapshot_reasons": {
"auto": "Created automatically",
"explicit": "Created by your explicit request",
"pre_restore": "Created as a precaution before risky restore",
"unknown": "Unknown"
}
},
"storage": {
"card_title": "Server Storage",

View File

@ -20,6 +20,7 @@ query AllBackupSnapshots {
displayName
id
}
reason
}
}
}
@ -98,4 +99,4 @@ mutation ForgetSnapshot($snapshotId: String!) {
...basicMutationReturnFields
}
}
}
}

View File

@ -1486,6 +1486,13 @@ const documentNodeQueryAllBackupSnapshots = DocumentNode(definitions: [
),
]),
),
FieldNode(
name: NameNode(value: 'reason'),
alias: null,
arguments: [],
directives: [],
selectionSet: null,
),
FieldNode(
name: NameNode(value: '__typename'),
alias: null,
@ -1801,6 +1808,7 @@ class Query$AllBackupSnapshots$backup$allSnapshots {
required this.id,
required this.createdAt,
required this.service,
required this.reason,
this.$__typename = 'SnapshotInfo',
});
@ -1809,12 +1817,14 @@ class Query$AllBackupSnapshots$backup$allSnapshots {
final l$id = json['id'];
final l$createdAt = json['createdAt'];
final l$service = json['service'];
final l$reason = json['reason'];
final l$$__typename = json['__typename'];
return Query$AllBackupSnapshots$backup$allSnapshots(
id: (l$id as String),
createdAt: dateTimeFromJson(l$createdAt),
service: Query$AllBackupSnapshots$backup$allSnapshots$service.fromJson(
(l$service as Map<String, dynamic>)),
reason: fromJson$Enum$BackupReason((l$reason as String)),
$__typename: (l$$__typename as String),
);
}
@ -1825,6 +1835,8 @@ class Query$AllBackupSnapshots$backup$allSnapshots {
final Query$AllBackupSnapshots$backup$allSnapshots$service service;
final Enum$BackupReason reason;
final String $__typename;
Map<String, dynamic> toJson() {
@ -1835,6 +1847,8 @@ class Query$AllBackupSnapshots$backup$allSnapshots {
_resultData['createdAt'] = dateTimeToJson(l$createdAt);
final l$service = service;
_resultData['service'] = l$service.toJson();
final l$reason = reason;
_resultData['reason'] = toJson$Enum$BackupReason(l$reason);
final l$$__typename = $__typename;
_resultData['__typename'] = l$$__typename;
return _resultData;
@ -1845,11 +1859,13 @@ class Query$AllBackupSnapshots$backup$allSnapshots {
final l$id = id;
final l$createdAt = createdAt;
final l$service = service;
final l$reason = reason;
final l$$__typename = $__typename;
return Object.hashAll([
l$id,
l$createdAt,
l$service,
l$reason,
l$$__typename,
]);
}
@ -1878,6 +1894,11 @@ class Query$AllBackupSnapshots$backup$allSnapshots {
if (l$service != lOther$service) {
return false;
}
final l$reason = reason;
final lOther$reason = other.reason;
if (l$reason != lOther$reason) {
return false;
}
final l$$__typename = $__typename;
final lOther$$__typename = other.$__typename;
if (l$$__typename != lOther$$__typename) {
@ -1910,6 +1931,7 @@ abstract class CopyWith$Query$AllBackupSnapshots$backup$allSnapshots<TRes> {
String? id,
DateTime? createdAt,
Query$AllBackupSnapshots$backup$allSnapshots$service? service,
Enum$BackupReason? reason,
String? $__typename,
});
CopyWith$Query$AllBackupSnapshots$backup$allSnapshots$service<TRes>
@ -1933,6 +1955,7 @@ class _CopyWithImpl$Query$AllBackupSnapshots$backup$allSnapshots<TRes>
Object? id = _undefined,
Object? createdAt = _undefined,
Object? service = _undefined,
Object? reason = _undefined,
Object? $__typename = _undefined,
}) =>
_then(Query$AllBackupSnapshots$backup$allSnapshots(
@ -1943,6 +1966,9 @@ class _CopyWithImpl$Query$AllBackupSnapshots$backup$allSnapshots<TRes>
service: service == _undefined || service == null
? _instance.service
: (service as Query$AllBackupSnapshots$backup$allSnapshots$service),
reason: reason == _undefined || reason == null
? _instance.reason
: (reason as Enum$BackupReason),
$__typename: $__typename == _undefined || $__typename == null
? _instance.$__typename
: ($__typename as String),
@ -1965,6 +1991,7 @@ class _CopyWithStubImpl$Query$AllBackupSnapshots$backup$allSnapshots<TRes>
String? id,
DateTime? createdAt,
Query$AllBackupSnapshots$backup$allSnapshots$service? service,
Enum$BackupReason? reason,
String? $__typename,
}) =>
_res;

View File

@ -75,6 +75,22 @@ type AutoUpgradeSettingsMutationReturn implements MutationReturnInterface {
allowReboot: Boolean!
}
type AutobackupQuotas {
last: Int!
daily: Int!
weekly: Int!
monthly: Int!
yearly: Int!
}
input AutobackupQuotasInput {
last: Int!
daily: Int!
weekly: Int!
monthly: Int!
yearly: Int!
}
type Backup {
configuration: BackupConfiguration!
allSnapshots: [SnapshotInfo!]!
@ -85,6 +101,7 @@ type BackupConfiguration {
encryptionKey: String!
isInitialized: Boolean!
autobackupPeriod: Int
autobackupQuotas: AutobackupQuotas!
locationName: String
locationId: String
}
@ -93,6 +110,7 @@ type BackupMutations {
initializeRepository(repository: InitializeRepositoryInput!): GenericBackupConfigReturn!
removeRepository: GenericBackupConfigReturn!
setAutobackupPeriod(period: Int = null): GenericBackupConfigReturn!
setAutobackupQuotas(quotas: AutobackupQuotasInput!): GenericBackupConfigReturn!
startBackup(serviceId: String!): GenericJobMutationReturn!
restoreBackup(snapshotId: String!, strategy: RestoreStrategy! = DOWNLOAD_VERIFY_OVERWRITE): GenericJobMutationReturn!
forgetSnapshot(snapshotId: String!): GenericMutationReturn!
@ -106,6 +124,12 @@ enum BackupProvider {
FILE
}
enum BackupReason {
EXPLICIT
AUTO
PRE_RESTORE
}
"""Date with time (isoformat)"""
scalar DateTime
@ -326,6 +350,7 @@ type SnapshotInfo {
id: String!
service: Service!
createdAt: DateTime!
reason: BackupReason!
}
input SshMutationInput {

View File

@ -141,6 +141,185 @@ class _CopyWithStubImpl$Input$AutoUpgradeSettingsInput<TRes>
_res;
}
class Input$AutobackupQuotasInput {
factory Input$AutobackupQuotasInput({
required int last,
required int daily,
required int weekly,
required int monthly,
required int yearly,
}) =>
Input$AutobackupQuotasInput._({
r'last': last,
r'daily': daily,
r'weekly': weekly,
r'monthly': monthly,
r'yearly': yearly,
});
Input$AutobackupQuotasInput._(this._$data);
factory Input$AutobackupQuotasInput.fromJson(Map<String, dynamic> data) {
final result$data = <String, dynamic>{};
final l$last = data['last'];
result$data['last'] = (l$last as int);
final l$daily = data['daily'];
result$data['daily'] = (l$daily as int);
final l$weekly = data['weekly'];
result$data['weekly'] = (l$weekly as int);
final l$monthly = data['monthly'];
result$data['monthly'] = (l$monthly as int);
final l$yearly = data['yearly'];
result$data['yearly'] = (l$yearly as int);
return Input$AutobackupQuotasInput._(result$data);
}
Map<String, dynamic> _$data;
int get last => (_$data['last'] as int);
int get daily => (_$data['daily'] as int);
int get weekly => (_$data['weekly'] as int);
int get monthly => (_$data['monthly'] as int);
int get yearly => (_$data['yearly'] as int);
Map<String, dynamic> toJson() {
final result$data = <String, dynamic>{};
final l$last = last;
result$data['last'] = l$last;
final l$daily = daily;
result$data['daily'] = l$daily;
final l$weekly = weekly;
result$data['weekly'] = l$weekly;
final l$monthly = monthly;
result$data['monthly'] = l$monthly;
final l$yearly = yearly;
result$data['yearly'] = l$yearly;
return result$data;
}
CopyWith$Input$AutobackupQuotasInput<Input$AutobackupQuotasInput>
get copyWith => CopyWith$Input$AutobackupQuotasInput(
this,
(i) => i,
);
@override
bool operator ==(Object other) {
if (identical(this, other)) {
return true;
}
if (!(other is Input$AutobackupQuotasInput) ||
runtimeType != other.runtimeType) {
return false;
}
final l$last = last;
final lOther$last = other.last;
if (l$last != lOther$last) {
return false;
}
final l$daily = daily;
final lOther$daily = other.daily;
if (l$daily != lOther$daily) {
return false;
}
final l$weekly = weekly;
final lOther$weekly = other.weekly;
if (l$weekly != lOther$weekly) {
return false;
}
final l$monthly = monthly;
final lOther$monthly = other.monthly;
if (l$monthly != lOther$monthly) {
return false;
}
final l$yearly = yearly;
final lOther$yearly = other.yearly;
if (l$yearly != lOther$yearly) {
return false;
}
return true;
}
@override
int get hashCode {
final l$last = last;
final l$daily = daily;
final l$weekly = weekly;
final l$monthly = monthly;
final l$yearly = yearly;
return Object.hashAll([
l$last,
l$daily,
l$weekly,
l$monthly,
l$yearly,
]);
}
}
abstract class CopyWith$Input$AutobackupQuotasInput<TRes> {
factory CopyWith$Input$AutobackupQuotasInput(
Input$AutobackupQuotasInput instance,
TRes Function(Input$AutobackupQuotasInput) then,
) = _CopyWithImpl$Input$AutobackupQuotasInput;
factory CopyWith$Input$AutobackupQuotasInput.stub(TRes res) =
_CopyWithStubImpl$Input$AutobackupQuotasInput;
TRes call({
int? last,
int? daily,
int? weekly,
int? monthly,
int? yearly,
});
}
class _CopyWithImpl$Input$AutobackupQuotasInput<TRes>
implements CopyWith$Input$AutobackupQuotasInput<TRes> {
_CopyWithImpl$Input$AutobackupQuotasInput(
this._instance,
this._then,
);
final Input$AutobackupQuotasInput _instance;
final TRes Function(Input$AutobackupQuotasInput) _then;
static const _undefined = <dynamic, dynamic>{};
TRes call({
Object? last = _undefined,
Object? daily = _undefined,
Object? weekly = _undefined,
Object? monthly = _undefined,
Object? yearly = _undefined,
}) =>
_then(Input$AutobackupQuotasInput._({
..._instance._$data,
if (last != _undefined && last != null) 'last': (last as int),
if (daily != _undefined && daily != null) 'daily': (daily as int),
if (weekly != _undefined && weekly != null) 'weekly': (weekly as int),
if (monthly != _undefined && monthly != null)
'monthly': (monthly as int),
if (yearly != _undefined && yearly != null) 'yearly': (yearly as int),
}));
}
class _CopyWithStubImpl$Input$AutobackupQuotasInput<TRes>
implements CopyWith$Input$AutobackupQuotasInput<TRes> {
_CopyWithStubImpl$Input$AutobackupQuotasInput(this._res);
TRes _res;
call({
int? last,
int? daily,
int? weekly,
int? monthly,
int? yearly,
}) =>
_res;
}
class Input$InitializeRepositoryInput {
factory Input$InitializeRepositoryInput({
required Enum$BackupProvider provider,
@ -1310,6 +1489,34 @@ Enum$BackupProvider fromJson$Enum$BackupProvider(String value) {
}
}
enum Enum$BackupReason { EXPLICIT, AUTO, PRE_RESTORE, $unknown }
String toJson$Enum$BackupReason(Enum$BackupReason e) {
switch (e) {
case Enum$BackupReason.EXPLICIT:
return r'EXPLICIT';
case Enum$BackupReason.AUTO:
return r'AUTO';
case Enum$BackupReason.PRE_RESTORE:
return r'PRE_RESTORE';
case Enum$BackupReason.$unknown:
return r'$unknown';
}
}
Enum$BackupReason fromJson$Enum$BackupReason(String value) {
switch (value) {
case r'EXPLICIT':
return Enum$BackupReason.EXPLICIT;
case r'AUTO':
return Enum$BackupReason.AUTO;
case r'PRE_RESTORE':
return Enum$BackupReason.PRE_RESTORE;
default:
return Enum$BackupReason.$unknown;
}
}
enum Enum$DnsProvider { CLOUDFLARE, DIGITALOCEAN, DESEC, $unknown }
String toJson$Enum$DnsProvider(Enum$DnsProvider e) {

View File

@ -11,6 +11,7 @@ class Backup {
time: snapshot.createdAt,
serviceId: snapshot.service.id,
fallbackServiceName: snapshot.service.displayName,
reason: snapshot.reason,
);
Backup({
@ -18,6 +19,7 @@ class Backup {
required this.id,
required this.serviceId,
required this.fallbackServiceName,
required this.reason,
});
// Time of the backup
@ -26,6 +28,16 @@ class Backup {
final String id;
final String serviceId;
final String fallbackServiceName;
final Enum$BackupReason reason;
}
extension BackupReasonExtension on Enum$BackupReason {
String get displayName => switch (this) {
Enum$BackupReason.AUTO => 'backup.snapshot_reasons.auto',
Enum$BackupReason.EXPLICIT => 'backup.snapshot_reasons.explicit',
Enum$BackupReason.PRE_RESTORE => 'backup.snapshot_reasons.pre_restore',
Enum$BackupReason.$unknown => 'backup.snapshot_reasons.unknown',
};
}
class BackupConfiguration {

View File

@ -99,6 +99,18 @@ class _SnapshotModalState extends State<SnapshotModal> {
),
),
SnapshotIdListTile(snapshotId: widget.snapshot.id),
ListTile(
leading: Icon(
Icons.info_outline,
color: Theme.of(context).colorScheme.onSurface,
),
title: Text(
'backup.snapshot_reason_title'.tr(),
),
subtitle: Text(
widget.snapshot.reason.displayName.tr(),
),
),
if (service != null)
Column(
children: [