Skip to content

Commit

Permalink
Merge branch 'main' into support-http-etags-and-if-none-match-header
Browse files Browse the repository at this point in the history
  • Loading branch information
mergify[bot] authored Feb 27, 2025
2 parents 4642fd8 + 3bd563d commit 5c00db7
Show file tree
Hide file tree
Showing 117 changed files with 1,260 additions and 1,923 deletions.
1 change: 1 addition & 0 deletions .ci/aui/runChecks.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ INITIAL_DIR=$(pwd)
cd Applications/AdminUi
dart pub global activate melos
melos bootstrap
melos generate_translations
melos analyze
melos format
15 changes: 14 additions & 1 deletion Applications/AdminApi/src/AdminApi/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,20 @@ RUN dotnet publish /p:ContinuousIntegrationBuild=true /p:UseAppHost=false --no-r
RUN dotnet publish /p:ContinuousIntegrationBuild=true --configuration Release --output /app/publish/health "/src/Applications/HealthCheck/src/HealthCheck.csproj"

#### Build Flutter Admin UI ####
FROM ghcr.io/cirruslabs/flutter:3.27.3 AS flutter-build-env
FROM ghcr.io/cirruslabs/android-sdk:34 AS flutter-build-env

USER root

ENV FLUTTER_HOME=/sdks/flutter
ENV FLUTTER_ROOT=$FLUTTER_HOME
ENV PATH=${PATH}:${FLUTTER_HOME}/bin:${FLUTTER_HOME}/bin/cache/dart-sdk/bin

RUN curl -sLO https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_3.29.0-stable.tar.xz \
&& mkdir -p ${FLUTTER_HOME} \
&& tar -xf flutter_linux_3.29.0-stable.tar.xz -C /sdks/ \
&& chown -R root:root ${FLUTTER_HOME}

RUN flutter doctor

COPY Applications/AdminUi /src
WORKDIR /src
Expand Down
4 changes: 4 additions & 0 deletions Applications/AdminUi/analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,7 @@ linter:
public_member_api_docs: false
always_use_package_imports: false
avoid_setters_without_getters: false
require_trailing_commas: false

formatter:
page_width: 150
3 changes: 3 additions & 0 deletions Applications/AdminUi/apps/admin_ui/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,6 @@ app.*.map.json
/android/app/debug
/android/app/profile
/android/app/release

# generated files
lib/generated/
3 changes: 3 additions & 0 deletions Applications/AdminUi/apps/admin_ui/l10n.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
synthetic-package: false
arb-dir: lib/l10n
output-dir: lib/generated/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart
preferred-supported-locales: [en]
use-escaping: false
3 changes: 2 additions & 1 deletion Applications/AdminUi/apps/admin_ui/lib/core/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ class Gaps {
static const SizedBox w40 = SizedBox(width: 40);
}

final kIsDesktop = !kIsWeb &&
final kIsDesktop =
!kIsWeb &&
(defaultTargetPlatform == TargetPlatform.linux ||
defaultTargetPlatform == TargetPlatform.macOS ||
defaultTargetPlatform == TargetPlatform.windows);
14 changes: 3 additions & 11 deletions Applications/AdminUi/apps/admin_ui/lib/core/extensions.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:get_it/get_it.dart';

import '../generated/l10n/app_localizations.dart';
import 'theme/theme.dart';

extension AppLocalizationsExtension on BuildContext {
Expand All @@ -22,18 +22,10 @@ extension GetCustomColors on BuildContext {
}

extension SetClipboardDataWithSnack on BuildContext {
void setClipboardDataWithSuccessNotification({
required String clipboardText,
required String successMessage,
}) {
void setClipboardDataWithSuccessNotification({required String clipboardText, required String successMessage}) {
Clipboard.setData(ClipboardData(text: clipboardText));

ScaffoldMessenger.of(this).showSnackBar(
SnackBar(
content: Text(successMessage),
showCloseIcon: true,
),
);
ScaffoldMessenger.of(this).showSnackBar(SnackBar(content: Text(successMessage), showCloseIcon: true));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,7 @@ import 'package:get_it/get_it.dart';
import '../constants.dart';
import '../extensions.dart';

Future<void> showAddQuotaDialog({
required BuildContext context,
required VoidCallback onQuotaAdded,
String? tierId,
String? identityAddress,
}) async {
Future<void> showAddQuotaDialog({required BuildContext context, required VoidCallback onQuotaAdded, String? tierId, String? identityAddress}) async {
assert(tierId != null || identityAddress != null, 'Either tierId or address must be provided');
assert(tierId == null || identityAddress == null, 'Only one of tierId or address can be provided');

Expand All @@ -22,20 +17,23 @@ Future<void> showAddQuotaDialog({

await showDialog<void>(
context: context,
builder: (BuildContext context) => _AssignQuotaDialog(
availableMetrics: metrics.data,
addQuota: ({required String metricKey, required int max, required String period}) {
if (tierId != null) {
return GetIt.I.get<AdminApiClient>().quotas.createTierQuota(tierId: tierId, metricKey: metricKey, max: max, period: period);
}

return GetIt.I
.get<AdminApiClient>()
.identities
.createIndividualQuota(address: identityAddress!, metricKey: metricKey, max: max, period: period);
},
onQuotaAdded: onQuotaAdded,
),
builder:
(BuildContext context) => _AssignQuotaDialog(
availableMetrics: metrics.data,
addQuota: ({required String metricKey, required int max, required String period}) {
if (tierId != null) {
return GetIt.I.get<AdminApiClient>().quotas.createTierQuota(tierId: tierId, metricKey: metricKey, max: max, period: period);
}

return GetIt.I.get<AdminApiClient>().identities.createIndividualQuota(
address: identityAddress!,
metricKey: metricKey,
max: max,
period: period,
);
},
onQuotaAdded: onQuotaAdded,
),
);
}

Expand All @@ -44,11 +42,7 @@ class _AssignQuotaDialog extends StatefulWidget {
final Future<ApiResponse<dynamic>> Function({required String metricKey, required int max, required String period}) addQuota;
final VoidCallback onQuotaAdded;

const _AssignQuotaDialog({
required this.availableMetrics,
required this.addQuota,
required this.onQuotaAdded,
});
const _AssignQuotaDialog({required this.availableMetrics, required this.addQuota, required this.onQuotaAdded});

@override
State<_AssignQuotaDialog> createState() => _AssignQuotaDialogState();
Expand Down Expand Up @@ -94,19 +88,13 @@ class _AssignQuotaDialogState extends State<_AssignQuotaDialog> {
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.all(8),
child: Text('*${context.l10n.required}'),
),
Padding(padding: const EdgeInsets.all(8), child: Text('*${context.l10n.required}')),
Gaps.h32,
DropdownButtonFormField(
value: _selectedMetric,
items: widget.availableMetrics.map((metric) => DropdownMenuItem(value: metric.key, child: Text(metric.displayName))).toList(),
onChanged: _saving ? null : (String? selected) => setState(() => _selectedMetric = selected),
decoration: InputDecoration(
border: const OutlineInputBorder(),
labelText: '${context.l10n.metric}*',
),
decoration: InputDecoration(border: const OutlineInputBorder(), labelText: '${context.l10n.metric}*'),
),
Gaps.h24,
TextField(
Expand All @@ -131,10 +119,7 @@ class _AssignQuotaDialogState extends State<_AssignQuotaDialog> {
DropdownMenuItem(value: 'Year', child: Text(context.l10n.year)),
],
onChanged: _saving ? null : (String? selected) => setState(() => _selectedPeriod = selected),
decoration: InputDecoration(
border: const OutlineInputBorder(),
labelText: '${context.l10n.period}*',
),
decoration: InputDecoration(border: const OutlineInputBorder(), labelText: '${context.l10n.period}*'),
),
if (_errorMessage != null)
Padding(
Expand All @@ -145,14 +130,8 @@ class _AssignQuotaDialogState extends State<_AssignQuotaDialog> {
),
),
actions: [
OutlinedButton(
onPressed: _saving ? null : () => Navigator.of(context, rootNavigator: true).pop(),
child: Text(context.l10n.cancel),
),
FilledButton(
onPressed: _isValid && !_saving ? _addQuota : null,
child: Text(context.l10n.assign),
),
OutlinedButton(onPressed: _saving ? null : () => Navigator.of(context, rootNavigator: true).pop(), child: Text(context.l10n.cancel)),
FilledButton(onPressed: _isValid && !_saving ? _addQuota : null, child: Text(context.l10n.assign)),
],
),
);
Expand All @@ -163,11 +142,7 @@ class _AssignQuotaDialogState extends State<_AssignQuotaDialog> {

assert(_selectedMetric != null && _maxAmount != null && _selectedPeriod != null, 'Invalid State');

final response = await widget.addQuota(
metricKey: _selectedMetric!,
max: _maxAmount!,
period: _selectedPeriod!,
);
final response = await widget.addQuota(metricKey: _selectedMetric!, max: _maxAmount!, period: _selectedPeriod!);

if (response.hasError) {
setState(() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,15 @@ Future<void> showChangeMaxIdentitiesDialog({
}) async {
await showDialog<void>(
context: context,
builder: (BuildContext context) => _ShowChangeMaxIdentitiesDialog(
onMaxIdentitiesUpdated: onMaxIdentitiesUpdated,
clientDetails: clientDetails,
),
builder: (BuildContext context) => _ShowChangeMaxIdentitiesDialog(onMaxIdentitiesUpdated: onMaxIdentitiesUpdated, clientDetails: clientDetails),
);
}

class _ShowChangeMaxIdentitiesDialog extends StatefulWidget {
final VoidCallback onMaxIdentitiesUpdated;
final Client clientDetails;

const _ShowChangeMaxIdentitiesDialog({
required this.onMaxIdentitiesUpdated,
required this.clientDetails,
});
const _ShowChangeMaxIdentitiesDialog({required this.onMaxIdentitiesUpdated, required this.clientDetails});

@override
State<_ShowChangeMaxIdentitiesDialog> createState() => _ShowChangeMaxIdentitiesDialogState();
Expand Down Expand Up @@ -99,26 +93,26 @@ class _ShowChangeMaxIdentitiesDialogState extends State<_ShowChangeMaxIdentities
}

final response = await GetIt.I.get<AdminApiClient>().clients.updateClient(
widget.clientDetails.clientId,
defaultTier: widget.clientDetails.defaultTier,
maxIdentities: _maxIdentities,
);
widget.clientDetails.clientId,
defaultTier: widget.clientDetails.defaultTier,
maxIdentities: _maxIdentities,
);

if (!mounted) return;

if (response.hasError) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(context.l10n.maxIdentities_error_message), duration: const Duration(seconds: 3)),
);
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text(context.l10n.maxIdentities_error_message), duration: const Duration(seconds: 3)));

setState(() => _saving = false);

return;
}

ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(context.l10n.maxIdentities_success_message), duration: const Duration(seconds: 3)),
);
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text(context.l10n.maxIdentities_success_message), duration: const Duration(seconds: 3)));

widget.onMaxIdentitiesUpdated();

Expand Down
50 changes: 20 additions & 30 deletions Applications/AdminUi/apps/admin_ui/lib/core/modals/change_tier.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,23 @@ Future<void> showChangeTierDialog({

await showDialog<void>(
context: context,
builder: (BuildContext context) => _ShowChangeTierDialog(
onTierUpdated: onTierUpdated,
currentTier: (clientDetails?.defaultTier ?? identityDetails?.tierId)!,
assignTier: ({required String tierId}) {
if (clientDetails != null) {
return GetIt.I.get<AdminApiClient>().clients.updateClient(
builder:
(BuildContext context) => _ShowChangeTierDialog(
onTierUpdated: onTierUpdated,
currentTier: (clientDetails?.defaultTier ?? identityDetails?.tierId)!,
assignTier: ({required String tierId}) {
if (clientDetails != null) {
return GetIt.I.get<AdminApiClient>().clients.updateClient(
clientDetails.clientId,
defaultTier: tierId,
maxIdentities: clientDetails.maxIdentities,
);
}
}

return GetIt.I.get<AdminApiClient>().identities.updateIdentity(identityDetails!.address, tierId: tierId);
},
availableTiers: availableTiers,
),
return GetIt.I.get<AdminApiClient>().identities.updateIdentity(identityDetails!.address, tierId: tierId);
},
availableTiers: availableTiers,
),
);
}

Expand All @@ -42,12 +43,7 @@ class _ShowChangeTierDialog extends StatefulWidget {
final List<TierOverview> availableTiers;
final String currentTier;

const _ShowChangeTierDialog({
required this.onTierUpdated,
required this.availableTiers,
required this.assignTier,
required this.currentTier,
});
const _ShowChangeTierDialog({required this.onTierUpdated, required this.availableTiers, required this.assignTier, required this.currentTier});

@override
State<_ShowChangeTierDialog> createState() => _ShowChangeTierDialogState();
Expand Down Expand Up @@ -78,17 +74,15 @@ class _ShowChangeTierDialogState extends State<_ShowChangeTierDialog> {
value: _selectedTier,
decoration: const InputDecoration(border: OutlineInputBorder()),
onChanged: _saving ? null : (String? newValue) => setState(() => _selectedTier = newValue!),
items: widget.availableTiers.where((tier) => tier.canBeManuallyAssigned || tier.canBeUsedAsDefaultForClient).map((TierOverview tier) {
return DropdownMenuItem<String>(value: tier.id, child: Text(tier.name));
}).toList(),
items:
widget.availableTiers.where((tier) => tier.canBeManuallyAssigned || tier.canBeUsedAsDefaultForClient).map((TierOverview tier) {
return DropdownMenuItem<String>(value: tier.id, child: Text(tier.name));
}).toList(),
),
),
actions: [
OutlinedButton(onPressed: _saving ? null : () => Navigator.of(context, rootNavigator: true).pop(), child: Text(context.l10n.cancel)),
FilledButton(
onPressed: _saving || _selectedTier == widget.currentTier ? null : _changeTier,
child: Text(context.l10n.change),
),
FilledButton(onPressed: _saving || _selectedTier == widget.currentTier ? null : _changeTier, child: Text(context.l10n.change)),
],
),
);
Expand All @@ -102,18 +96,14 @@ class _ShowChangeTierDialogState extends State<_ShowChangeTierDialog> {
if (!mounted) return;

if (response.hasError) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(context.l10n.changeTierDialog_error), duration: const Duration(seconds: 3)),
);
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(context.l10n.changeTierDialog_error), duration: const Duration(seconds: 3)));

setState(() => _saving = false);

return;
}

ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(context.l10n.changeTierDialog_success), duration: const Duration(seconds: 3)),
);
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(context.l10n.changeTierDialog_success), duration: const Duration(seconds: 3)));

widget.onTierUpdated();

Expand Down
Loading

0 comments on commit 5c00db7

Please sign in to comment.