diff --git a/CHANGELOG.md b/CHANGELOG.md
index 111c1491a..9bef40e30 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,58 +1,5 @@
# Changelog
-## [1.0.8-rc14] - unstable
-
-### Added
-
-* [PostIt] Ajout d'un `BillingQueryDetailsPageViewModel` et de sa page associee pour afficher le detail d'une commande billing depuis l'historique.
-* [PostIt] Ajout d'un mode detail avec section metier (statut, date, description, motif, infos) et section technique repliable (code, client, provision, lieu, prestations).
-* [PostIt] Ajout d'un badge de statut enrichi (couleur + pictogramme) sur le detail d'une commande pour visualiser l'etat en un coup d'oeil.
-* [PostIt] Ajout d'un bloc d'actions rapide en tete du detail (`Retour`, `Ouvrir en edition`) pour eviter le scroll jusqu'au bas de page.
-* [PostIt] Ajout d'un style monospace sur les metadonnees techniques (code billing, client, provision, lieu, prestations) pour faciliter la lecture des identifiants et valeurs brutes.
-
-### Changed
-
-* [PostIt] Le bouton d'ouverture depuis la liste billing ouvre maintenant une page de detail dediee avant l'eventuelle edition.
-* [PostIt] Amelioration UX des pages billing: badges de statut colores, actions remontees en haut de page, et typographie monospace sur les metadonnees techniques.
-
-### Fixed
-
-* [Yavsc.Api] Correction d'un 500 sur le refresh du catalogue d'activites lorsque `Activity.Description` est `NULL` en base (nullabilite explicite + projection null-safe + gardes sur codes vides).
-* [Yavsc.Api] Correction des erreurs 400/500 sur les routes billing (`Rdv`, `Brush`, `MBrush`) en imposant `ClientId` depuis l'utilisateur authentifie et en ignorant les champs server-owned lors de la validation modele.
-* [Yavsc.Api] Correction du `PUT /api/v1/billing/Rdv/{id}`: mise a jour controlee de l'entite existante (et non remplacement brut du graphe JSON), ce qui supprime les `BadRequest` parasites.
-* [Yavsc.Api] Correction PostgreSQL `timestamptz` sur RDV: normalisation UTC de `EventDate` sur `POST/PUT /api/v1/billing/Rdv` pour eviter l'erreur `Cannot write DateTime with Kind=Local`.
-* [Yavsc.Api] Correction du flux FrontOffice accept/reject de query: sauvegarde avec contexte utilisateur et fallback d'injection pour `IBillingService` afin d'eviter les erreurs serveur en environnement de test.
-* [Yavsc.Blogs] Correction des `BadRequest` sur `POST/PUT /api/v1/blogspot` avec payload JSON (PostIt): les proprietes de navigation/serveur (`Author`, `Tags`, `Comments`, audit) ne bloquent plus la validation.
-* [Yavsc.Org] Correction du flux MVC de creation de commentaire: `SaveChangesAsync(userId)` est utilise pour renseigner les champs d'audit requis (`UserCreated`/`UserModified`).
-* [Yavsc.Api.Test] Stabilisation des fixtures de seed billing: remplissage des metadonnees d'audit (`UserCreated`, `UserModified`, dates) pour eviter les echecs SQLite `NOT NULL`.
-
-## [1.0.8-rc13] - unstable
-
-### Added
-
-* [PostIt] Integration d'un selecteur de lieu RDV base sur Mapsui (carte interactive dans le formulaire `Rdv`).
-* [PostIt] Ajout d'un marqueur de position et d'une action de recentrage sur la carte RDV.
-* [PostIt] Ajout d'un service de reverse geocoding pour suggerer une adresse a partir des coordonnees carte.
-* [PostIt] Cache et debounce des resolutions d'adresse RDV pour limiter les appels reseau et lisser l'UX.
-* [PostIt.Tests] Nouvelles non-regressions sur le panneau d'adresse suggeree RDV et le comportement de la carte.
-* [Yavsc.Abstract] Activation de `#nullable enable annotations` sur les fichiers legacy avec annotations nullable.
-* [Yavsc.Server] Activation de `#nullable enable annotations` sur les fichiers legacy avec annotations nullable.
-
-### Changed
-
-* [PostIt] Generalisation de la barre de statut d'action (severite explicite) sur pages principales, dialogues et formulaires billing.
-* [PostIt] Harmonisation des messages de statut utilisateur en francais.
-* [PostIt] Renforcement des gardes de navigation dans les flux de gestion des membres de cercle.
-* [PostIt] Le flux RDV conserve l'adresse saisie manuellement et propose l'adresse resolue comme suggestion explicite.
-* [PostIt] Le flux de geolocalisation RDV tolere les positions proches dans le cache de suggestion d'adresse.
-
-### Fixed
-
-* [PostIt.Desktop] Correction d'un crash au demarrage OIDC (`No authority specified`) via durcissement des valeurs par defaut de configuration d'authentification.
-* [PostIt] Correction de la persistance des settings: l'etat runtime de statut n'est plus serialize dans le JSON utilisateur.
-* [PostIt.Tests] Ajout d'un verrou de non-regression sur le premier chargement des settings.
-* [PostIt] Correction du binding de la date RDV: `DatePicker.SelectedDate` est aligne sur un proxy `DateTimeOffset?` (`EventDateSelection`).
-
## [1.0.8-rc12] - unstable
### Added
@@ -66,14 +13,12 @@
* [PostIt] Les avatars ne sont plus relies en string sur `Image.Source`: ils sont telecharges et lies en `Bitmap`.
* [Yavsc.Api.Client] `ActivityApiClient` accepte une base d'avatar dediee et construit les URLs avatar depuis l'autorite d'identification.
-* [PostIt] Les clients Activites/Billing utilisent maintenant `ApiUrl` en lecture dynamique: un changement via Parametres prend effet sans redemarrer l'application (apres sauvegarde et rafraichissement de la page).
* [PostIt] Le header de `MainPage` n'utilise plus `ScrollViewer`; remplacement par une barre de commandes basee sur `WrapPanel`.
* [PostIt] Alignement de la navigation blogs: renommage `PushMainPageAsync` -> `PushBlogsPageAsync` et ajustement de `HomePageViewModel`.
### Fixed
-* [PostIt.Android] Correction d'un 404 sur la page Activites au premier lancement: la configuration embarquee pointait `ApiUrl` vers le host Blogs au lieu de l'API metier.
-* [PostIt] Correction du bouton Sauver de la page Parametres: binding vers `SaveCommand` pour persister correctement `ApiUrl`/`BlogsApiUrl`.
+néant
## [1.0.8-rc11] - unstable
diff --git a/src/PostIt/Directory.Packages.props b/src/PostIt/Directory.Packages.props
index 2f27340e9..4dd4b2889 100644
--- a/src/PostIt/Directory.Packages.props
+++ b/src/PostIt/Directory.Packages.props
@@ -16,8 +16,6 @@
-
-
diff --git a/src/PostIt/PostIt.Tests/ActivitiesPageViewModelTests.cs b/src/PostIt/PostIt.Tests/ActivitiesPageViewModelTests.cs
index 04cc0f314..2e8d3e544 100644
--- a/src/PostIt/PostIt.Tests/ActivitiesPageViewModelTests.cs
+++ b/src/PostIt/PostIt.Tests/ActivitiesPageViewModelTests.cs
@@ -39,22 +39,6 @@ public class ActivitiesPageViewModelTests
Assert.Equal("https://business.example/api/v1/billing/Rdv", api.Paths[3]);
}
- [Fact]
- public async Task ActivityApiClient_uses_updated_business_base_without_restart()
- {
- var api = new StubActivityApi();
- var baseUrl = "https://business-a.example/api/v1/";
- var client = new ActivityApiClient(api, () => baseUrl);
-
- await client.GetCatalogAsync(ct: TestContext.Current.CancellationToken);
-
- baseUrl = "https://business-b.example/api/v1/";
- await client.GetUsersAsync("brush", TestContext.Current.CancellationToken);
-
- Assert.Equal("https://business-a.example/api/v1/activity/catalog", api.Paths[0]);
- Assert.Equal("https://business-b.example/api/v1/activity/brush/users", api.Paths[1]);
- }
-
[Fact]
public async Task RefreshAsync_loads_first_activity_then_specialization_performers()
{
diff --git a/src/PostIt/PostIt.Tests/BillingCommandPageViewModelTests.cs b/src/PostIt/PostIt.Tests/BillingCommandPageViewModelTests.cs
index 17fcc968c..c7b5b926b 100644
--- a/src/PostIt/PostIt.Tests/BillingCommandPageViewModelTests.cs
+++ b/src/PostIt/PostIt.Tests/BillingCommandPageViewModelTests.cs
@@ -115,89 +115,6 @@ public class BillingCommandPageViewModelTests
}
}
- [Fact]
- public void ApplyLocationFromMap_sets_coordinates_and_updates_status()
- {
- var api = new RecordingApi();
- var client = new BillingApiClient(api, "https://business.example/api/v1/");
- var vm =
- new CommandFormSummary { Id = 12, ActionName = "Rdv", Title = "Rendez-vous" }
- .CreateCommandPageViewModel(
- new ActivityInfo { Code = "dev", Name = "Développement" },
- new ActivityUserDisplayItem { PerformerId = "perf-1", UserName = "Alice" },
- client) as RdvViewModel;
-
- vm!.Address = string.Empty;
- vm.ApplyLocationFromMap(48.85661234, 2.35224567);
-
- Assert.Equal(48.856612, vm.Latitude);
- Assert.Equal(2.352246, vm.Longitude);
- Assert.Contains("Position sélectionnée", vm.StatusMessage, StringComparison.OrdinalIgnoreCase);
- }
-
- [Fact]
- public void EventDateSelection_round_trips_with_EventDate_for_DatePicker_binding()
- {
- var api = new RecordingApi();
- var client = new BillingApiClient(api, "https://business.example/api/v1/");
- var vm =
- new CommandFormSummary { Id = 12, ActionName = "Rdv", Title = "Rendez-vous" }
- .CreateCommandPageViewModel(
- new ActivityInfo { Code = "dev", Name = "Développement" },
- new ActivityUserDisplayItem { PerformerId = "perf-1", UserName = "Alice" },
- client) as RdvViewModel;
-
- var selected = new DateTimeOffset(2026, 9, 7, 14, 30, 0, TimeSpan.FromHours(2));
- vm!.EventDateSelection = selected;
-
- Assert.Equal(selected.LocalDateTime, vm.EventDate);
- Assert.Equal(vm.EventDate, vm.EventDateSelection!.Value.LocalDateTime);
- }
-
- [Fact]
- public void ApplyResolvedAddress_populates_empty_address_directly()
- {
- var api = new RecordingApi();
- var client = new BillingApiClient(api, "https://business.example/api/v1/");
- var vm =
- new CommandFormSummary { Id = 12, ActionName = "Rdv", Title = "Rendez-vous" }
- .CreateCommandPageViewModel(
- new ActivityInfo { Code = "dev", Name = "Développement" },
- new ActivityUserDisplayItem { PerformerId = "perf-1", UserName = "Alice" },
- client) as RdvViewModel;
-
- vm!.Address = string.Empty;
- vm.ApplyResolvedAddress("10 rue de Rivoli, 75001 Paris");
-
- Assert.Equal("10 rue de Rivoli, 75001 Paris", vm.Address);
- Assert.False(vm.HasSuggestedAddress);
- }
-
- [Fact]
- public void ApplyResolvedAddress_preserves_manual_address_and_exposes_suggestion()
- {
- var api = new RecordingApi();
- var client = new BillingApiClient(api, "https://business.example/api/v1/");
- var vm =
- new CommandFormSummary { Id = 12, ActionName = "Rdv", Title = "Rendez-vous" }
- .CreateCommandPageViewModel(
- new ActivityInfo { Code = "dev", Name = "Développement" },
- new ActivityUserDisplayItem { PerformerId = "perf-1", UserName = "Alice" },
- client) as RdvViewModel;
-
- vm!.Address = "Saisie manuelle";
- vm.ApplyResolvedAddress("10 rue de Rivoli, 75001 Paris");
-
- Assert.Equal("Saisie manuelle", vm.Address);
- Assert.True(vm.HasSuggestedAddress);
- Assert.Equal("10 rue de Rivoli, 75001 Paris", vm.SuggestedAddress);
-
- vm.ApplySuggestedAddressCommand.Execute(null);
-
- Assert.Equal("10 rue de Rivoli, 75001 Paris", vm.Address);
- Assert.False(vm.HasSuggestedAddress);
- }
-
[Fact]
public async Task InitializeAsync_loads_prestations_for_brush_and_submit_posts_selected_prestation()
{
diff --git a/src/PostIt/PostIt.Tests/NominatimReverseGeocodingServiceTests.cs b/src/PostIt/PostIt.Tests/NominatimReverseGeocodingServiceTests.cs
deleted file mode 100644
index 4eceb7a2f..000000000
--- a/src/PostIt/PostIt.Tests/NominatimReverseGeocodingServiceTests.cs
+++ /dev/null
@@ -1,72 +0,0 @@
-using System.Net;
-using System.Text;
-using PostIt.Services;
-
-namespace PostIt.Tests;
-
-public class NominatimReverseGeocodingServiceTests
-{
- [Fact]
- public async Task TryResolveAddressAsync_formats_compact_street_address_from_nominatim_payload()
- {
- var handler = new StubHandler("""
- {
- "display_name": "6, Place de l'Hôtel-de-Ville - Esplanade de la Libération, Paris, 75004, France",
- "address": {
- "house_number": "6",
- "road": "Place de l'Hôtel-de-Ville - Esplanade de la Libération",
- "postcode": "75004",
- "city": "Paris"
- }
- }
- """);
-
- var service = new NominatimReverseGeocodingService(new HttpClient(handler)
- {
- BaseAddress = new Uri("https://nominatim.openstreetmap.org/")
- });
-
- var result = await service.TryResolveAddressAsync(48.8566, 2.3522);
-
- Assert.Equal("6, Place de l'Hôtel-de-Ville - Esplanade de la Libération, 75004, Paris", result);
- Assert.NotNull(handler.LastRequest);
- Assert.Contains("reverse?format=jsonv2", handler.LastRequest!.RequestUri!.ToString(), StringComparison.Ordinal);
- }
-
- [Fact]
- public async Task TryResolveAddressAsync_returns_null_on_unsuccessful_response()
- {
- var handler = new StubHandler("{}", HttpStatusCode.TooManyRequests);
- var service = new NominatimReverseGeocodingService(new HttpClient(handler)
- {
- BaseAddress = new Uri("https://nominatim.openstreetmap.org/")
- });
-
- var result = await service.TryResolveAddressAsync(48.8566, 2.3522);
-
- Assert.Null(result);
- }
-
- private sealed class StubHandler : HttpMessageHandler
- {
- private readonly string _payload;
- private readonly HttpStatusCode _statusCode;
-
- public HttpRequestMessage? LastRequest { get; private set; }
-
- public StubHandler(string payload, HttpStatusCode statusCode = HttpStatusCode.OK)
- {
- _payload = payload;
- _statusCode = statusCode;
- }
-
- protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
- {
- LastRequest = request;
- return Task.FromResult(new HttpResponseMessage(_statusCode)
- {
- Content = new StringContent(_payload, Encoding.UTF8, "application/json")
- });
- }
- }
-}
\ No newline at end of file
diff --git a/src/PostIt/PostIt.Tests/RdvPageHeadlessTests.cs b/src/PostIt/PostIt.Tests/RdvPageHeadlessTests.cs
deleted file mode 100644
index fdf8689ab..000000000
--- a/src/PostIt/PostIt.Tests/RdvPageHeadlessTests.cs
+++ /dev/null
@@ -1,79 +0,0 @@
-using Avalonia.Controls;
-using Avalonia.Headless.XUnit;
-using PostIt.ViewModels;
-using PostIt.ViewModels.Commands;
-using PostIt.Views.Commands;
-using Yavsc.Abstract.Workflow;
-using Yavsc.Api.Client;
-
-namespace PostIt.Tests;
-
-public class RdvPageHeadlessTests
-{
- [AvaloniaFact]
- public void Suggested_address_panel_is_hidden_by_default()
- {
- var page = CreatePage(out _);
-
- var panel = page.FindControl("SuggestedAddressPanel");
- var progress = page.FindControl("SuggestedAddressProgress");
-
- Assert.NotNull(panel);
- Assert.NotNull(progress);
- Assert.False(panel!.IsVisible);
- Assert.False(progress!.IsVisible);
- }
-
- [AvaloniaFact]
- public async Task Suggested_address_panel_and_spinner_follow_viewmodel_state()
- {
- var page = CreatePage(out var vm);
- var panel = page.FindControl("SuggestedAddressPanel")!;
- var progress = page.FindControl("SuggestedAddressProgress")!;
- var applyButton = page.FindControl("ApplySuggestedAddressButton")!;
-
- vm.Address = "Saisie manuelle";
- vm.NotifyReverseGeocodingStarted();
- await Task.Delay(50);
-
- Assert.True(panel.IsVisible);
- Assert.True(progress.IsVisible);
- Assert.False(applyButton.IsVisible);
-
- vm.ApplyResolvedAddress("10 rue de Rivoli, 75001 Paris");
- await Task.Delay(50);
-
- Assert.True(panel.IsVisible);
- Assert.False(progress.IsVisible);
- Assert.True(applyButton.IsVisible);
- }
-
- private static RdvPage CreatePage(out RdvViewModel vm)
- {
- vm = new RdvViewModel(
- new ActivityInfo { Code = "dev", Name = "Développement" },
- new ActivityUserDisplayItem { PerformerId = "perf-1", UserName = "Alice" },
- new CommandFormSummary { Id = 12, ActionName = "Rdv", Title = "Rendez-vous" },
- new BillingApiClient(new RecordingApi(), "https://business.example/api/v1/"));
-
- var page = new RdvPage { DataContext = vm };
- var nav = new NavigationPage();
- _ = nav.PushAsync(page);
- var window = new Window { Content = nav };
- window.Show();
- return page;
- }
-
- private sealed class RecordingApi : IYavscApiClient
- {
- public HttpClient Http { get; } = new();
-
- public Task CallAsync(HttpMethod method, string path, object? body = null, CancellationToken ct = default)
- => Task.FromResult(default(T)!);
-
- public Task CallAsync(HttpMethod method, string path, object? body = null, CancellationToken ct = default)
- => Task.CompletedTask;
-
- public ValueTask DisposeAsync() => ValueTask.CompletedTask;
- }
-}
\ No newline at end of file
diff --git a/src/PostIt/PostIt.Tests/RdvPageTests.cs b/src/PostIt/PostIt.Tests/RdvPageTests.cs
deleted file mode 100644
index e9d20cc96..000000000
--- a/src/PostIt/PostIt.Tests/RdvPageTests.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-using PostIt.Views.Commands;
-
-namespace PostIt.Tests;
-
-public class RdvPageTests
-{
- [Fact]
- public void AreCoordinatesClose_returns_true_for_nearby_points_within_cache_tolerance()
- {
- var result = RdvPage.AreCoordinatesClose(
- 48.8566,
- 2.3522,
- 48.85665,
- 2.35225);
-
- Assert.True(result);
- }
-
- [Fact]
- public void AreCoordinatesClose_returns_false_for_points_outside_cache_tolerance()
- {
- var result = RdvPage.AreCoordinatesClose(
- 48.8566,
- 2.3522,
- 48.85685,
- 2.3522);
-
- Assert.False(result);
- }
-}
\ No newline at end of file
diff --git a/src/PostIt/PostIt.Tests/SettingsLoadTests.cs b/src/PostIt/PostIt.Tests/SettingsLoadTests.cs
index 069b6ac96..3f8dc02b9 100644
--- a/src/PostIt/PostIt.Tests/SettingsLoadTests.cs
+++ b/src/PostIt/PostIt.Tests/SettingsLoadTests.cs
@@ -173,51 +173,4 @@ public class SettingsLoadTests
Assert.NotNull(roundTrip);
Assert.Equal("bonjour", roundTrip.SearchText);
}
-
- ///
- /// First-start regression guard: older settings payloads can
- /// still contain ActionStatus from a previous write. This
- /// runtime-only UI state must not be persisted anymore and must
- /// not break deserialization when present.
- ///
- [Fact]
- public void ActionStatus_is_not_persisted_and_legacy_payload_with_it_still_deserializes()
- {
- var settings = new PostIt.ViewModels.Settings
- {
- Authentication = new AuthenticationSettings
- {
- Authority = "https://example.test/",
- ClientId = "postit-tests",
- Scopes = new[] { "openid" }
- }
- };
-
- var serialized = JsonSerializer.Serialize(settings);
- Assert.DoesNotContain("\"ActionStatus\"", serialized, StringComparison.Ordinal);
-
- const string legacyPayload = """
- {
- "Authentication": {
- "Authority": "https://example.test/",
- "ClientId": "postit-tests",
- "Scopes": ["openid"],
- "RedirectUri": "postit://callback"
- },
- "DarkMode": false,
- "BlogsApiUrl": "https://blogs.example.test/api/v1/",
- "ApiUrl": "https://api.example.test/api/v1/",
- "SearchText": "hello",
- "ActionStatus": {
- "Message": "runtime only",
- "Severity": "Error"
- }
- }
- """;
-
- var roundTrip = JsonSerializer.Deserialize(legacyPayload);
-
- Assert.NotNull(roundTrip);
- Assert.Equal("hello", roundTrip.SearchText);
- }
}
diff --git a/src/PostIt/PostIt/Controls/StatusBar.axaml b/src/PostIt/PostIt/Controls/StatusBar.axaml
deleted file mode 100644
index eaa6f5a09..000000000
--- a/src/PostIt/PostIt/Controls/StatusBar.axaml
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/src/PostIt/PostIt/Controls/StatusBar.axaml.cs b/src/PostIt/PostIt/Controls/StatusBar.axaml.cs
deleted file mode 100644
index 975f9b2f9..000000000
--- a/src/PostIt/PostIt/Controls/StatusBar.axaml.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using Avalonia.Controls;
-
-namespace PostIt.Controls;
-
-public partial class StatusBar : UserControl
-{
- public StatusBar()
- {
- InitializeComponent();
- }
-}
diff --git a/src/PostIt/PostIt/Helpers/ServiceCollectionHelpers.cs b/src/PostIt/PostIt/Helpers/ServiceCollectionHelpers.cs
index c0831b290..f95f31e30 100644
--- a/src/PostIt/PostIt/Helpers/ServiceCollectionHelpers.cs
+++ b/src/PostIt/PostIt/Helpers/ServiceCollectionHelpers.cs
@@ -26,11 +26,10 @@ public static class ServiceCollectionHelpers
var userSearchClient = new UserSearchClient(api, settings.BlogsApiUrl);
var activityClient = new ActivityApiClient(
api,
- () => settings.ApiUrl,
- () => settings.Authentication?.Authority);
- var billingClient = new BillingApiClient(api, () => settings.ApiUrl);
+ settings.ApiUrl,
+ settings.Authentication?.Authority);
+ var billingClient = new BillingApiClient(api, settings.ApiUrl);
var userDirectory = new UserDirectory(userSearchClient);
- var reverseGeocoding = new NominatimReverseGeocodingService();
// Vues
services.AddSingleton();
@@ -57,7 +56,6 @@ public static class ServiceCollectionHelpers
services.AddTransient();
services.AddTransient();
services.AddTransient();
- services.AddTransient();
// ViewModels
services.AddSingleton(settings);
services.AddSingleton(api);
@@ -67,7 +65,6 @@ public static class ServiceCollectionHelpers
services.AddSingleton(userSearchClient);
services.AddSingleton(activityClient);
services.AddSingleton(billingClient);
- services.AddSingleton(reverseGeocoding);
services.AddSingleton(userDirectory);
services.AddSingleton();
services.AddSingleton();
diff --git a/src/PostIt/PostIt/PostIt.csproj b/src/PostIt/PostIt/PostIt.csproj
index 09632bdf8..177e346d3 100644
--- a/src/PostIt/PostIt/PostIt.csproj
+++ b/src/PostIt/PostIt/PostIt.csproj
@@ -29,8 +29,6 @@
None
All
-
-
diff --git a/src/PostIt/PostIt/Services/IReverseGeocodingService.cs b/src/PostIt/PostIt/Services/IReverseGeocodingService.cs
deleted file mode 100644
index 0e62fe9dc..000000000
--- a/src/PostIt/PostIt/Services/IReverseGeocodingService.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace PostIt.Services;
-
-public interface IReverseGeocodingService
-{
- Task TryResolveAddressAsync(double latitude, double longitude, CancellationToken cancellationToken = default);
-}
\ No newline at end of file
diff --git a/src/PostIt/PostIt/Services/NominatimReverseGeocodingService.cs b/src/PostIt/PostIt/Services/NominatimReverseGeocodingService.cs
deleted file mode 100644
index f9ddb2f6a..000000000
--- a/src/PostIt/PostIt/Services/NominatimReverseGeocodingService.cs
+++ /dev/null
@@ -1,119 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Net.Http;
-using System.Net.Http.Headers;
-using System.Text.Json;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace PostIt.Services;
-
-public sealed class NominatimReverseGeocodingService : IReverseGeocodingService
-{
- private static readonly Uri BaseUri = new("https://nominatim.openstreetmap.org/");
- private readonly HttpClient _httpClient;
-
- public NominatimReverseGeocodingService(HttpClient? httpClient = null)
- {
- _httpClient = httpClient ?? CreateDefaultClient();
- }
-
- public async Task TryResolveAddressAsync(double latitude, double longitude, CancellationToken cancellationToken = default)
- {
- var requestUri = BuildReverseUri(latitude, longitude);
-
- try
- {
- using var response = await _httpClient.GetAsync(requestUri, cancellationToken).ConfigureAwait(false);
- if (!response.IsSuccessStatusCode)
- return null;
-
- await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
- using var json = await JsonDocument.ParseAsync(stream, cancellationToken: cancellationToken).ConfigureAwait(false);
- return FormatAddress(json.RootElement);
- }
- catch (OperationCanceledException)
- {
- throw;
- }
- catch
- {
- return null;
- }
- }
-
- private static HttpClient CreateDefaultClient()
- {
- var client = new HttpClient
- {
- BaseAddress = BaseUri,
- Timeout = TimeSpan.FromSeconds(10),
- };
- client.DefaultRequestHeaders.UserAgent.Clear();
- client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("PostIt", "1.1"));
- client.DefaultRequestHeaders.AcceptLanguage.Add(new StringWithQualityHeaderValue("fr-FR"));
- client.DefaultRequestHeaders.AcceptLanguage.Add(new StringWithQualityHeaderValue("fr", 0.9));
- return client;
- }
-
- private static Uri BuildReverseUri(double latitude, double longitude)
- {
- var lat = latitude.ToString("0.######", CultureInfo.InvariantCulture);
- var lon = longitude.ToString("0.######", CultureInfo.InvariantCulture);
- var path = $"reverse?format=jsonv2&addressdetails=1&accept-language=fr&zoom=18&lat={lat}&lon={lon}";
- return new Uri(path, UriKind.Relative);
- }
-
- private static string? FormatAddress(JsonElement root)
- {
- if (root.TryGetProperty("address", out var address))
- {
- var street = JoinNonEmpty(
- TryGetString(address, "house_number"),
- TryGetString(address, "road"));
-
- var locality = JoinNonEmpty(
- TryGetString(address, "postcode"),
- TryGetString(address, "city")
- ?? TryGetString(address, "town")
- ?? TryGetString(address, "village")
- ?? TryGetString(address, "municipality"));
-
- var formatted = JoinNonEmpty(street, locality);
- if (!string.IsNullOrWhiteSpace(formatted))
- return formatted;
- }
-
- if (root.TryGetProperty("display_name", out var displayName))
- {
- var value = displayName.GetString();
- if (!string.IsNullOrWhiteSpace(value))
- return value;
- }
-
- return null;
- }
-
- private static string? TryGetString(JsonElement element, string propertyName)
- {
- return element.TryGetProperty(propertyName, out var property)
- ? property.GetString()
- : null;
- }
-
- private static string? JoinNonEmpty(params string?[] values)
- {
- List? parts = null;
- foreach (var value in values)
- {
- if (string.IsNullOrWhiteSpace(value))
- continue;
-
- parts ??= new List();
- parts.Add(value.Trim());
- }
-
- return parts is null || parts.Count == 0 ? null : string.Join(", ", parts);
- }
-}
\ No newline at end of file
diff --git a/src/PostIt/PostIt/ViewLocator.cs b/src/PostIt/PostIt/ViewLocator.cs
index f866e1bac..0055a9e60 100644
--- a/src/PostIt/PostIt/ViewLocator.cs
+++ b/src/PostIt/PostIt/ViewLocator.cs
@@ -19,7 +19,7 @@ namespace PostIt;
public class ViewLocator : IDataTemplate
{
- public Control Build(object? data)
+ public Control Build(object? data)
{
try
{
@@ -49,12 +49,10 @@ public class ViewLocator : IDataTemplate
AddCircleMemberDialogViewModel => services.GetRequiredService(),
CirclesPageViewModel => services.GetRequiredService(),
PostAclDialogViewModel => services.GetRequiredService(),
- BillingQueriesPageViewModel => services.GetRequiredService(),
- BillingQueryDetailsPageViewModel => services.GetRequiredService(),
null => new TextBlock { Text = "No view for " },
_ => new TextBlock { Text = $"No view for {data.GetType().Name}" }
};
}
- public bool Match(object? data) => data is ViewModelBase;
+ public bool Match(object? data) => data is ViewModelBase;
}
diff --git a/src/PostIt/PostIt/ViewModels/ActionStatusViewModelExtensions.cs b/src/PostIt/PostIt/ViewModels/ActionStatusViewModelExtensions.cs
deleted file mode 100644
index 614d477c8..000000000
--- a/src/PostIt/PostIt/ViewModels/ActionStatusViewModelExtensions.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-namespace PostIt.ViewModels;
-
-public interface IActionStatusViewModel
-{
- string StatusMessage { get; set; }
- StatusNotice ActionStatus { get; set; }
-}
-
-public static class ActionStatusViewModelExtensions
-{
- public static void SetInfoStatus(this IActionStatusViewModel viewModel, string message)
- => viewModel.SetStatus(message, StatusSeverity.Info);
-
- public static void SetWarningStatus(this IActionStatusViewModel viewModel, string message)
- => viewModel.SetStatus(message, StatusSeverity.Warning);
-
- public static void SetErrorStatus(this IActionStatusViewModel viewModel, string message)
- => viewModel.SetStatus(message, StatusSeverity.Error);
-
- public static void SetStatus(this IActionStatusViewModel viewModel, string message, StatusSeverity severity)
- {
- var normalizedMessage = string.IsNullOrWhiteSpace(message) ? "Pret." : message.Trim();
-
- viewModel.StatusMessage = normalizedMessage;
- viewModel.ActionStatus = severity switch
- {
- StatusSeverity.Error => StatusNotice.Error(normalizedMessage),
- StatusSeverity.Warning => StatusNotice.Warning(normalizedMessage),
- _ => StatusNotice.Info(normalizedMessage),
- };
- }
-}
\ No newline at end of file
diff --git a/src/PostIt/PostIt/ViewModels/ActivitiesPageViewModel.cs b/src/PostIt/PostIt/ViewModels/ActivitiesPageViewModel.cs
index bd13faf9b..2dc8938f3 100644
--- a/src/PostIt/PostIt/ViewModels/ActivitiesPageViewModel.cs
+++ b/src/PostIt/PostIt/ViewModels/ActivitiesPageViewModel.cs
@@ -13,7 +13,7 @@ using Yavsc.Api.Client;
namespace PostIt.ViewModels;
-public partial class ActivitiesPageViewModel : ViewModelBase, IActionStatusViewModel
+public partial class ActivitiesPageViewModel : ViewModelBase
{
private readonly ActivityApiClient _client;
private readonly BillingApiClient _billingClient;
@@ -43,9 +43,6 @@ public partial class ActivitiesPageViewModel : ViewModelBase, IActionStatusViewM
[ObservableProperty]
public partial string StatusMessage { get; set; } = "Choisissez une activité.";
- [ObservableProperty]
- public partial StatusNotice ActionStatus { get; set; } = StatusNotice.Info("Choisissez une activité.");
-
public ActivityInfo? CurrentActivity => SelectedSpecialization ?? SelectedActivity;
public string SelectedActivityLabel => SelectedActivity?.Name ?? "(aucune activité)";
public string CurrentActivityLabel => CurrentActivity?.Name ?? "(aucune)";
@@ -89,11 +86,11 @@ public partial class ActivitiesPageViewModel : ViewModelBase, IActionStatusViewM
}
catch (HttpRequestException ex) when (ex.StatusCode is HttpStatusCode.Unauthorized or HttpStatusCode.Forbidden)
{
- this.SetWarningStatus("Accès refusé pour les activités (scope 'api'). Déconnectez puis reconnectez-vous.");
+ StatusMessage = "Accès refusé pour les activités (scope 'api'). Déconnectez puis reconnectez-vous.";
}
catch (Exception ex)
{
- this.SetErrorStatus($"Erreur: {ex.Message}");
+ StatusMessage = $"Erreur: {ex.Message}";
}
}
@@ -105,11 +102,11 @@ public partial class ActivitiesPageViewModel : ViewModelBase, IActionStatusViewM
}
catch (HttpRequestException ex) when (ex.StatusCode is HttpStatusCode.Unauthorized or HttpStatusCode.Forbidden)
{
- this.SetWarningStatus("Accès refusé pour les activités (scope 'api'). Déconnectez puis reconnectez-vous.");
+ StatusMessage = "Accès refusé pour les activités (scope 'api'). Déconnectez puis reconnectez-vous.";
}
catch (Exception ex)
{
- this.SetErrorStatus($"Erreur: {ex.Message}");
+ StatusMessage = $"Erreur: {ex.Message}";
}
}
@@ -126,7 +123,7 @@ public partial class ActivitiesPageViewModel : ViewModelBase, IActionStatusViewM
await ShowActivityAsync(first);
if (first is null)
{
- this.SetInfoStatus("Aucune activité disponible.");
+ StatusMessage = "Aucune activité disponible.";
}
}
catch (HttpRequestException ex) when (ex.StatusCode is HttpStatusCode.Unauthorized or HttpStatusCode.Forbidden)
@@ -134,14 +131,14 @@ public partial class ActivitiesPageViewModel : ViewModelBase, IActionStatusViewM
Activities = new ObservableCollection();
Specializations = new ObservableCollection();
Performers = new ObservableCollection();
- this.SetWarningStatus("Accès refusé pour les activités (scope 'api'). Déconnectez puis reconnectez-vous.");
+ StatusMessage = "Accès refusé pour les activités (scope 'api'). Déconnectez puis reconnectez-vous.";
}
catch (Exception ex)
{
Activities = new ObservableCollection();
Specializations = new ObservableCollection();
Performers = new ObservableCollection();
- this.SetErrorStatus($"Erreur: {ex.Message}");
+ StatusMessage = $"Erreur: {ex.Message}";
}
finally
{
@@ -233,19 +230,19 @@ public partial class ActivitiesPageViewModel : ViewModelBase, IActionStatusViewM
Performers = new ObservableCollection(items);
SelectedPerformer = null;
- this.SetInfoStatus($"{activity.Name} · {Performers.Count} utilisateur(s)");
+ StatusMessage = $"{activity.Name} · {Performers.Count} utilisateur(s)";
}
catch (HttpRequestException ex) when (ex.StatusCode is HttpStatusCode.Unauthorized or HttpStatusCode.Forbidden)
{
Performers = new ObservableCollection();
SelectedPerformer = null;
- this.SetWarningStatus("Accès refusé pour les activités (scope 'api'). Déconnectez puis reconnectez-vous.");
+ StatusMessage = "Accès refusé pour les activités (scope 'api'). Déconnectez puis reconnectez-vous.";
}
catch (Exception ex)
{
Performers = new ObservableCollection();
SelectedPerformer = null;
- this.SetErrorStatus($"Erreur: {ex.Message}");
+ StatusMessage = $"Erreur: {ex.Message}";
}
finally
{
@@ -262,7 +259,7 @@ public partial class ActivitiesPageViewModel : ViewModelBase, IActionStatusViewM
{
if (SelectedPerformer is null || CurrentActivity is null)
{
- this.SetWarningStatus("Sélectionnez un utilisateur et une activité avec formulaire.");
+ StatusMessage = "Sélectionnez un utilisateur et une activité avec formulaire.";
return;
}
diff --git a/src/PostIt/PostIt/ViewModels/AddCircleMemberDialogViewModel.cs b/src/PostIt/PostIt/ViewModels/AddCircleMemberDialogViewModel.cs
index 635073d1a..88d01335a 100644
--- a/src/PostIt/PostIt/ViewModels/AddCircleMemberDialogViewModel.cs
+++ b/src/PostIt/PostIt/ViewModels/AddCircleMemberDialogViewModel.cs
@@ -29,7 +29,7 @@ namespace PostIt.ViewModels;
/// CirclesPage then calls
/// .
///
-public partial class AddCircleMemberDialogViewModel : ViewModelBase, IActionStatusViewModel
+public partial class AddCircleMemberDialogViewModel : ViewModelBase
{
private readonly IUserDirectory _directory;
@@ -46,10 +46,7 @@ public partial class AddCircleMemberDialogViewModel : ViewModelBase, IActionStat
public partial bool IsBusy { get; set; }
[ObservableProperty]
- public partial string StatusMessage { get; set; } = "Pret.";
-
- [ObservableProperty]
- public partial StatusNotice ActionStatus { get; set; } = StatusNotice.Info("Pret.");
+ public partial string StatusMessage { get; set; } = string.Empty;
///
/// Raised when the user confirms a selection. The hosting
@@ -82,7 +79,7 @@ public partial class AddCircleMemberDialogViewModel : ViewModelBase, IActionStat
if (string.IsNullOrWhiteSpace(SearchQuery))
{
Results.Clear();
- this.SetWarningStatus("Tapez un nom ou un email");
+ StatusMessage = "Tapez un nom ou un email";
return;
}
@@ -91,11 +88,11 @@ public partial class AddCircleMemberDialogViewModel : ViewModelBase, IActionStat
{
var hits = await _directory.SearchAsync(SearchQuery, CancellationToken.None).ConfigureAwait(true);
Results = new ObservableCollection(hits ?? Array.Empty());
- this.SetInfoStatus($"{Results.Count} résultat(s)");
+ StatusMessage = $"{Results.Count} résultat(s)";
}
catch (Exception ex)
{
- this.SetErrorStatus($"Erreur: {ex.Message}");
+ StatusMessage = $"Erreur: {ex.Message}";
}
finally
{
@@ -113,20 +110,18 @@ public partial class AddCircleMemberDialogViewModel : ViewModelBase, IActionStat
{
if (Selected is null)
{
- this.SetWarningStatus("Sélectionnez un utilisateur");
+ StatusMessage = "Sélectionnez un utilisateur";
return;
}
Confirmed?.Invoke(this, Selected);
- var app = App.Current as App
- ?? throw new InvalidOperationException("Application PostIt indisponible.");
+ var app = App.Current as App;
await app.GoBackAsync();
}
[RelayCommand]
public async Task CloseAsync()
{
- var app = App.Current as App
- ?? throw new InvalidOperationException("Application PostIt indisponible.");
+ var app = App.Current as App;
await app.GoBackAsync();
}
}
diff --git a/src/PostIt/PostIt/ViewModels/BillingQueriesPageViewModel.cs b/src/PostIt/PostIt/ViewModels/BillingQueriesPageViewModel.cs
index bccf97167..d5aba0215 100644
--- a/src/PostIt/PostIt/ViewModels/BillingQueriesPageViewModel.cs
+++ b/src/PostIt/PostIt/ViewModels/BillingQueriesPageViewModel.cs
@@ -14,7 +14,7 @@ using Yavsc.Abstract.Workflow;
namespace PostIt.ViewModels;
-public partial class BillingQueriesPageViewModel : ViewModelBase, IActionStatusViewModel
+public partial class BillingQueriesPageViewModel : ViewModelBase
{
private readonly BillingApiClient _billingClient;
@@ -36,14 +36,11 @@ public partial class BillingQueriesPageViewModel : ViewModelBase, IActionStatusV
[ObservableProperty]
public partial string StatusMessage { get; set; } = "Chargement des commandes...";
- [ObservableProperty]
- public partial StatusNotice ActionStatus { get; set; } = StatusNotice.Info("Chargement des commandes...");
-
public string Title => IsReadOnly
? $"Demandes en cours ({Form.Title})"
: $"Commandes {Form.Title}";
public string ContextLabel => $"{Performer.UserName} · {Activity.Name}";
- public bool CanOpenDetails => true;
+ public bool CanOpenDetails => !IsReadOnly;
public override bool CanNavigateNext
{
@@ -75,7 +72,7 @@ public partial class BillingQueriesPageViewModel : ViewModelBase, IActionStatusV
public Task InitializeAsync() => RefreshAsync();
- private bool CanOpenSelectedQuery() => SelectedQuery is not null;
+ private bool CanOpenSelectedQuery() => !IsReadOnly && SelectedQuery is not null;
[RelayCommand]
public async Task RefreshAsync()
@@ -93,17 +90,17 @@ public partial class BillingQueriesPageViewModel : ViewModelBase, IActionStatusV
.ToList();
Queries = new ObservableCollection(filtered);
- this.SetInfoStatus(BuildLoadedStatusMessage(filtered.Count));
+ StatusMessage = BuildLoadedStatusMessage(filtered.Count);
}
catch (HttpRequestException ex) when (ex.StatusCode is HttpStatusCode.Unauthorized or HttpStatusCode.Forbidden)
{
Queries = new ObservableCollection();
- this.SetWarningStatus("Accès refusé au billing (scope 'api'). Déconnectez puis reconnectez-vous.");
+ StatusMessage = "Accès refusé au billing (scope 'api'). Déconnectez puis reconnectez-vous.";
}
catch (Exception ex)
{
Queries = new ObservableCollection();
- this.SetErrorStatus($"Erreur: {ex.Message}");
+ StatusMessage = $"Erreur: {ex.Message}";
}
finally
{
@@ -114,9 +111,15 @@ public partial class BillingQueriesPageViewModel : ViewModelBase, IActionStatusV
[RelayCommand(CanExecute = nameof(CanOpenSelectedQuery))]
public async Task OpenSelectedQueryAsync()
{
+ if (IsReadOnly)
+ {
+ StatusMessage = "Mode lecture seule: l'ouverture en modification est désactivée.";
+ return;
+ }
+
if (SelectedQuery is null)
{
- this.SetWarningStatus("Sélectionnez une commande.");
+ StatusMessage = "Sélectionnez une commande.";
return;
}
@@ -130,22 +133,17 @@ public partial class BillingQueriesPageViewModel : ViewModelBase, IActionStatusV
try
{
var details = await _billingClient.GetQueryAsync(Form.ActionName, SelectedQuery.Id).ConfigureAwait(true);
- var vm = new BillingQueryDetailsPageViewModel(
- Activity,
- Performer,
- Form,
- _billingClient,
- details,
- IsReadOnly);
+ var vm = Form.CreateCommandPageViewModel(Activity, Performer, _billingClient);
+ await vm!.InitializeAsync(details).ConfigureAwait(true);
await app.PushPageAsync(vm).ConfigureAwait(true);
}
catch (HttpRequestException ex) when (ex.StatusCode is HttpStatusCode.Unauthorized or HttpStatusCode.Forbidden)
{
- this.SetWarningStatus("Accès refusé au billing (scope 'api'). Déconnectez puis reconnectez-vous.");
+ StatusMessage = "Accès refusé au billing (scope 'api'). Déconnectez puis reconnectez-vous.";
}
catch (Exception ex)
{
- this.SetErrorStatus($"Erreur lors de l'ouverture: {ex.Message}");
+ StatusMessage = $"Erreur lors de l'ouverture: {ex.Message}";
}
finally
{
diff --git a/src/PostIt/PostIt/ViewModels/BillingQueryDetailsPageViewModel.cs b/src/PostIt/PostIt/ViewModels/BillingQueryDetailsPageViewModel.cs
deleted file mode 100644
index cd13daaf1..000000000
--- a/src/PostIt/PostIt/ViewModels/BillingQueryDetailsPageViewModel.cs
+++ /dev/null
@@ -1,208 +0,0 @@
-using System;
-using System.Linq;
-using System.Threading.Tasks;
-using Avalonia;
-using CommunityToolkit.Mvvm.ComponentModel;
-using CommunityToolkit.Mvvm.Input;
-using PostIt.Helpers;
-using Yavsc;
-using Yavsc.Abstract.Workflow;
-using Yavsc.Api.Client;
-
-namespace PostIt.ViewModels;
-
-public partial class BillingQueryDetailsPageViewModel : ViewModelBase, IActionStatusViewModel
-{
- private readonly BillingApiClient _billingClient;
- private readonly BillingQueryDetailsDto _details;
-
- public ActivityInfo Activity { get; }
- public ActivityUserDisplayItem Performer { get; }
- public CommandFormSummary Form { get; }
- public bool IsReadOnly { get; }
-
- public long Id => _details.Id;
- public string Title => $"Detail commande #{_details.Id}";
- public string ContextLabel => $"{Performer.UserName} · {Activity.Name} · {Form.Title}";
- public string StatusLabel => _details.Status.ToString();
- public string StatusGlyph => GetStatusGlyph(_details.Status);
- public string StatusBadgeBackground => GetStatusBadgeBackground(_details.Status);
- public string StatusBadgeBorder => GetStatusBadgeBorder(_details.Status);
- public string StatusBadgeForeground => GetStatusBadgeForeground(_details.Status);
- public string TitleForeground => StatusBadgeForeground;
- public string BillingCode => _details.BillingCode;
- public string Description => EmptyAsPlaceholder(_details.Description, "(sans description)");
- public string Reason => EmptyAsPlaceholder(_details.Reason, "(aucun motif)");
- public string AdditionalInfo => EmptyAsPlaceholder(_details.AdditionalInfo, "(aucune info complementaire)");
- public string ClientId => EmptyAsPlaceholder(_details.ClientId, "(non renseigne)");
- public string EventDateLabel => _details.EventDate?.ToLocalTime().ToString("f") ?? "Date non precisee";
- public string ConsentLabel => _details.Consent ? "Oui" : "Non";
- public string ProvisionalLabel => _details.Provisional.HasValue ? _details.Provisional.Value.ToString("0.00") : "(non renseigne)";
- public string LocationLabel => BuildLocationLabel(_details.Location);
- public string PrestationsLabel => BuildPrestationsLabel(_details);
- public bool CanEdit => !IsReadOnly;
-
- [ObservableProperty]
- public partial bool IsBusy { get; set; }
-
- [ObservableProperty]
- public partial string StatusMessage { get; set; } = "Pret.";
-
- [ObservableProperty]
- public partial StatusNotice ActionStatus { get; set; } = StatusNotice.Info("Pret.");
-
- public override bool CanNavigateNext
- {
- get => false;
- protected set { _ = value; }
- }
-
- public override bool CanNavigatePrevious
- {
- get => true;
- protected set { _ = value; }
- }
-
- public BillingQueryDetailsPageViewModel(
- ActivityInfo activity,
- ActivityUserDisplayItem performer,
- CommandFormSummary form,
- BillingApiClient billingClient,
- BillingQueryDetailsDto details,
- bool isReadOnly)
- {
- Activity = activity ?? throw new ArgumentNullException(nameof(activity));
- Performer = performer ?? throw new ArgumentNullException(nameof(performer));
- Form = form ?? throw new ArgumentNullException(nameof(form));
- _billingClient = billingClient ?? throw new ArgumentNullException(nameof(billingClient));
- _details = details ?? throw new ArgumentNullException(nameof(details));
- IsReadOnly = isReadOnly;
-
- this.SetInfoStatus("Details de commande charges.");
- }
-
- [RelayCommand]
- private async Task OpenEditorAsync()
- {
- if (IsReadOnly)
- {
- this.SetWarningStatus("Mode lecture seule: edition desactivee.");
- return;
- }
-
- var app = (App?)Application.Current;
- if (app is null)
- {
- throw new InvalidOperationException("Application PostIt indisponible.");
- }
-
- IsBusy = true;
- try
- {
- var vm = Form.CreateCommandPageViewModel(Activity, Performer, _billingClient);
- if (vm is null)
- {
- this.SetWarningStatus("Ce formulaire n'est pas encore pris en charge en edition.");
- return;
- }
-
- await vm.InitializeAsync(_details).ConfigureAwait(true);
- await app.PushPageAsync(vm).ConfigureAwait(true);
- }
- catch (Exception ex)
- {
- this.SetErrorStatus($"Erreur lors de l'ouverture en edition: {ex.Message}");
- }
- finally
- {
- IsBusy = false;
- }
- }
-
- [RelayCommand]
- private async Task BackAsync()
- {
- var app = (App?)Application.Current;
- if (app is null)
- {
- throw new InvalidOperationException("Application PostIt indisponible.");
- }
-
- await app.GoBackAsync().ConfigureAwait(true);
- }
-
- private static string EmptyAsPlaceholder(string? value, string placeholder)
- => string.IsNullOrWhiteSpace(value) ? placeholder : value;
-
- private static string BuildLocationLabel(BillingLocationDto? location)
- {
- if (location is null)
- {
- return "(non renseignee)";
- }
-
- var text = EmptyAsPlaceholder(location.Address, "adresse vide");
- if (location.Latitude.HasValue && location.Longitude.HasValue)
- {
- text += $" ({location.Latitude.Value:0.####}, {location.Longitude.Value:0.####})";
- }
-
- return text;
- }
-
- private static string BuildPrestationsLabel(BillingQueryDetailsDto details)
- {
- if (details.PrestationIds.Count > 0)
- {
- return string.Join(", ", details.PrestationIds.Select(static id => id.ToString()));
- }
-
- return details.PrestationId.HasValue
- ? details.PrestationId.Value.ToString()
- : "(aucune)";
- }
-
- private static string GetStatusBadgeBackground(QueryStatus status)
- => status switch
- {
- QueryStatus.Accepted => "#E6F7EC",
- QueryStatus.InProgress => "#FFF4D6",
- QueryStatus.Rejected => "#FDECEA",
- QueryStatus.Failed => "#ECEFF1",
- QueryStatus.Success => "#E8F8EF",
- _ => "#EAF3FF",
- };
-
- private static string GetStatusBadgeBorder(QueryStatus status)
- => status switch
- {
- QueryStatus.Accepted => "#2E7D32",
- QueryStatus.InProgress => "#B26A00",
- QueryStatus.Rejected => "#C62828",
- QueryStatus.Failed => "#607D8B",
- QueryStatus.Success => "#1E8E3E",
- _ => "#2A5EA8",
- };
-
- private static string GetStatusBadgeForeground(QueryStatus status)
- => status switch
- {
- QueryStatus.Accepted => "#1B5E20",
- QueryStatus.InProgress => "#7A4A00",
- QueryStatus.Rejected => "#8E0000",
- QueryStatus.Failed => "#37474F",
- QueryStatus.Success => "#145A2A",
- _ => "#1A4178",
- };
-
- private static string GetStatusGlyph(QueryStatus status)
- => status switch
- {
- QueryStatus.Accepted => "OK",
- QueryStatus.InProgress => "~",
- QueryStatus.Rejected => "!",
- QueryStatus.Failed => "X",
- QueryStatus.Success => "V",
- _ => "i",
- };
-}
\ No newline at end of file
diff --git a/src/PostIt/PostIt/ViewModels/CirclesPageViewModel.cs b/src/PostIt/PostIt/ViewModels/CirclesPageViewModel.cs
index cd068b4f4..9cee3ea8c 100644
--- a/src/PostIt/PostIt/ViewModels/CirclesPageViewModel.cs
+++ b/src/PostIt/PostIt/ViewModels/CirclesPageViewModel.cs
@@ -34,7 +34,7 @@ namespace PostIt.ViewModels;
/// . The "remove"
/// command is per-row and runs inline.
///
-public partial class CirclesPageViewModel : ViewModelBase, IActionStatusViewModel
+public partial class CirclesPageViewModel : ViewModelBase
{
private readonly CircleApiClient _client;
@@ -63,10 +63,8 @@ public partial class CirclesPageViewModel : ViewModelBase, IActionStatusViewMode
public partial bool IsBusy { get; set; }
[ObservableProperty]
- public partial string StatusMessage { get; set; } = "Pret.";
+ public partial string StatusMessage { get; set; } = string.Empty;
- [ObservableProperty]
- public partial StatusNotice ActionStatus { get; set; } = StatusNotice.Info("Pret.");
public CirclesPageViewModel(CircleApiClient client)
{
@@ -102,11 +100,11 @@ public partial class CirclesPageViewModel : ViewModelBase, IActionStatusViewMode
{
var list = await _client.GetMyCirclesAsync();
Circles = new ObservableCollection(list ?? new());
- this.SetInfoStatus($"{Circles.Count} cercle(s)");
+ StatusMessage = $"{Circles.Count} cercle(s)";
}
catch (Exception ex)
{
- this.SetErrorStatus($"Erreur: {ex.Message}");
+ StatusMessage = $"Erreur: {ex.Message}";
}
finally
{
@@ -117,10 +115,8 @@ public partial class CirclesPageViewModel : ViewModelBase, IActionStatusViewMode
[RelayCommand]
internal async Task OpenAddMemberAsync()
{
- var app = Application.Current as App
- ?? throw new InvalidOperationException("Application PostIt indisponible.");
- var services = app.ServiceProvider
- ?? throw new InvalidOperationException("ServiceProvider PostIt indisponible.");
+ var app = Application.Current as App;
+ var services = app?.ServiceProvider;
var directory = services.GetRequiredService();
AddCircleMemberDialogViewModel model =
new AddCircleMemberDialogViewModel(directory);
@@ -151,11 +147,11 @@ public partial class CirclesPageViewModel : ViewModelBase, IActionStatusViewMode
{
var list = await _client.GetMembersAsync(circleId);
Members = new ObservableCollection(list ?? new());
- this.SetInfoStatus($"{Members.Count} membre(s)");
+ StatusMessage = $"{Members.Count} membre(s)";
}
catch (Exception ex)
{
- this.SetErrorStatus($"Erreur: {ex.Message}");
+ StatusMessage = $"Erreur: {ex.Message}";
Members = new ObservableCollection();
}
finally
@@ -170,7 +166,7 @@ public partial class CirclesPageViewModel : ViewModelBase, IActionStatusViewMode
SelectedCircle = null;
DraftName = string.Empty;
DraftPublic = false;
- this.SetInfoStatus("Nouveau cercle");
+ StatusMessage = "Nouveau cercle";
}
[RelayCommand]
@@ -180,7 +176,7 @@ public partial class CirclesPageViewModel : ViewModelBase, IActionStatusViewMode
SelectedCircle = circle;
DraftName = circle.Name;
DraftPublic = circle.Public;
- this.SetInfoStatus($"Édition de « {circle.Name} »");
+ StatusMessage = $"Édition de « {circle.Name} »";
}
[RelayCommand]
@@ -188,7 +184,7 @@ public partial class CirclesPageViewModel : ViewModelBase, IActionStatusViewMode
{
if (string.IsNullOrWhiteSpace(DraftName))
{
- this.SetWarningStatus("Le nom est obligatoire");
+ StatusMessage = "Le nom est obligatoire";
return;
}
@@ -202,22 +198,22 @@ public partial class CirclesPageViewModel : ViewModelBase, IActionStatusViewMode
Name = DraftName.Trim(),
Public = DraftPublic,
});
- this.SetStatus(
- created is null ? "Création échouée" : $"Cercle « {created.Name} » créé",
- created is null ? StatusSeverity.Warning : StatusSeverity.Info);
+ StatusMessage = created is null
+ ? "Création échouée"
+ : $"Cercle « {created.Name} » créé";
}
else
{
SelectedCircle.Name = DraftName.Trim();
SelectedCircle.Public = DraftPublic;
await _client.UpdateCircleAsync(SelectedCircle.Id, SelectedCircle);
- this.SetInfoStatus($"Cercle « {SelectedCircle.Name} » mis à jour");
+ StatusMessage = $"Cercle « {SelectedCircle.Name} » mis à jour";
}
await RefreshAsync();
}
catch (Exception ex)
{
- this.SetErrorStatus($"Erreur: {ex.Message}");
+ StatusMessage = $"Erreur: {ex.Message}";
}
finally
{
@@ -233,7 +229,7 @@ public partial class CirclesPageViewModel : ViewModelBase, IActionStatusViewMode
try
{
await _client.DeleteCircleAsync(circle.Id);
- this.SetInfoStatus($"Cercle « {circle.Name} » supprimé");
+ StatusMessage = $"Cercle « {circle.Name} » supprimé";
// If the deleted circle was the selected one,
// clear the selection so the Members view goes
// empty too (the partial setter on
@@ -244,7 +240,7 @@ public partial class CirclesPageViewModel : ViewModelBase, IActionStatusViewMode
}
catch (Exception ex)
{
- this.SetErrorStatus($"Erreur: {ex.Message}");
+ StatusMessage = $"Erreur: {ex.Message}";
}
finally
{
@@ -265,7 +261,7 @@ public partial class CirclesPageViewModel : ViewModelBase, IActionStatusViewMode
try
{
await _client.AddMemberAsync(SelectedCircle.Id, picked.Id);
- this.SetInfoStatus($"« {picked.DisplayName} » ajouté au cercle");
+ StatusMessage = $"« {picked.DisplayName} » ajouté au cercle";
await LoadMembersAsync(SelectedCircle.Id);
}
catch (Exception ex)
@@ -280,7 +276,7 @@ public partial class CirclesPageViewModel : ViewModelBase, IActionStatusViewMode
var msg = ex.Message.Contains("409") || ex.Message.Contains("Conflict")
? "Déjà membre du cercle"
: $"Erreur: {ex.Message}";
- this.SetStatus(msg, msg == "Déjà membre du cercle" ? StatusSeverity.Warning : StatusSeverity.Error);
+ StatusMessage = msg;
}
finally
{
@@ -301,11 +297,11 @@ public partial class CirclesPageViewModel : ViewModelBase, IActionStatusViewMode
{
await _client.RemoveMemberAsync(SelectedCircle.Id, member.Id);
Members.Remove(member);
- this.SetInfoStatus($"« {member.UserName} » retiré du cercle");
+ StatusMessage = $"« {member.UserName} » retiré du cercle";
}
catch (Exception ex)
{
- this.SetErrorStatus($"Erreur: {ex.Message}");
+ StatusMessage = $"Erreur: {ex.Message}";
}
finally
{
diff --git a/src/PostIt/PostIt/ViewModels/CommandFormsPageViewModel.cs b/src/PostIt/PostIt/ViewModels/CommandFormsPageViewModel.cs
index 533fbc380..71f5d67a0 100644
--- a/src/PostIt/PostIt/ViewModels/CommandFormsPageViewModel.cs
+++ b/src/PostIt/PostIt/ViewModels/CommandFormsPageViewModel.cs
@@ -11,7 +11,7 @@ using Yavsc.Api.Client;
namespace PostIt.ViewModels;
-public partial class CommandFormsPageViewModel : ViewModelBase, IActionStatusViewModel
+public partial class CommandFormsPageViewModel : ViewModelBase
{
private readonly BillingApiClient _billingClient;
@@ -25,10 +25,7 @@ public partial class CommandFormsPageViewModel : ViewModelBase, IActionStatusVie
public partial CommandFormSummary? SelectedForm { get; set; }
[ObservableProperty]
- public partial string StatusMessage { get; set; } = "Pret.";
-
- [ObservableProperty]
- public partial StatusNotice ActionStatus { get; set; } = StatusNotice.Info("Pret.");
+ public partial string StatusMessage { get; set; }
public string Title => $"Formulaires pour {Performer.UserName}";
public string ContextLabel => $"{Activity.Name} · {Forms.Count} formulaire(s)";
@@ -58,11 +55,9 @@ public partial class CommandFormsPageViewModel : ViewModelBase, IActionStatusVie
.OrderBy(f => f.Title)
.ThenBy(f => f.ActionName));
SelectedForm = Forms.FirstOrDefault();
- this.SetStatus(
- Forms.Count == 0
- ? "Aucun formulaire n'est disponible pour cette activité."
- : "Choisissez le formulaire à utiliser.",
- Forms.Count == 0 ? StatusSeverity.Warning : StatusSeverity.Info);
+ StatusMessage = Forms.Count == 0
+ ? "Aucun formulaire n'est disponible pour cette activité."
+ : "Choisissez le formulaire à utiliser.";
}
private bool CanOpenSelectedForm() => SelectedForm is not null;
@@ -76,7 +71,7 @@ public partial class CommandFormsPageViewModel : ViewModelBase, IActionStatusVie
{
if (SelectedForm is null)
{
- this.SetWarningStatus("Sélectionnez un formulaire.");
+ StatusMessage = "Sélectionnez un formulaire.";
return;
}
@@ -97,7 +92,7 @@ public partial class CommandFormsPageViewModel : ViewModelBase, IActionStatusVie
{
if (SelectedForm is null)
{
- this.SetWarningStatus("Sélectionnez un formulaire.");
+ StatusMessage = "Sélectionnez un formulaire.";
return;
}
@@ -117,7 +112,7 @@ public partial class CommandFormsPageViewModel : ViewModelBase, IActionStatusVie
{
if (SelectedForm is null)
{
- this.SetWarningStatus("Sélectionnez un formulaire.");
+ StatusMessage = "Sélectionnez un formulaire.";
return;
}
diff --git a/src/PostIt/PostIt/ViewModels/Commands/BillingCommandPageViewModel.cs b/src/PostIt/PostIt/ViewModels/Commands/BillingCommandPageViewModel.cs
index 5ad2b08f4..0ab76291d 100644
--- a/src/PostIt/PostIt/ViewModels/Commands/BillingCommandPageViewModel.cs
+++ b/src/PostIt/PostIt/ViewModels/Commands/BillingCommandPageViewModel.cs
@@ -9,7 +9,7 @@ using Yavsc.Models.Billing;
namespace PostIt.ViewModels;
-public abstract partial class BillingCommandPageViewModel : RemoteViewModelBase, IActionStatusViewModel
+public abstract partial class BillingCommandPageViewModel : RemoteViewModelBase
{
protected readonly BillingApiClient _billingClient;
@@ -21,10 +21,7 @@ public abstract partial class BillingCommandPageViewModel : RemoteViewModelBase,
public partial bool IsBusy { get; set; }
[ObservableProperty]
- public partial string StatusMessage { get; set; } = "Pret.";
-
- [ObservableProperty]
- public partial StatusNotice ActionStatus { get; set; } = StatusNotice.Info("Pret.");
+ public partial string StatusMessage { get; set; }
[ObservableProperty]
public partial string Reason { get; set; } = string.Empty;
@@ -78,7 +75,7 @@ public abstract partial class BillingCommandPageViewModel : RemoteViewModelBase,
Form = form ?? throw new ArgumentNullException(nameof(form));
_billingClient = billingClient ?? throw new ArgumentNullException(nameof(billingClient));
- this.SetInfoStatus(SupportMessage);
+ StatusMessage = SupportMessage;
}
partial void OnExistingQueryIdChanged(long? value)
diff --git a/src/PostIt/PostIt/ViewModels/Commands/BrushViewModel.cs b/src/PostIt/PostIt/ViewModels/Commands/BrushViewModel.cs
index 72d9ce8ea..d49fde803 100644
--- a/src/PostIt/PostIt/ViewModels/Commands/BrushViewModel.cs
+++ b/src/PostIt/PostIt/ViewModels/Commands/BrushViewModel.cs
@@ -58,20 +58,18 @@ public partial class BrushViewModel : RdvViewModel
SelectedPrestation = AvailablePrestations.FirstOrDefault();
}
- this.SetStatus(
- AvailablePrestations.Count == 0
- ? "Aucune prestation coiffure disponible."
- : SupportMessage,
- AvailablePrestations.Count == 0 ? StatusSeverity.Warning : StatusSeverity.Info);
+ StatusMessage = AvailablePrestations.Count == 0
+ ? "Aucune prestation coiffure disponible."
+ : SupportMessage;
}
catch (HttpRequestException ex)
when (ex.StatusCode is HttpStatusCode.Unauthorized or HttpStatusCode.Forbidden)
{
- this.SetWarningStatus("Accès refusé au catalogue de prestations (scope 'api'). Déconnectez puis reconnectez-vous.");
+ StatusMessage = "Accès refusé au catalogue de prestations (scope 'api'). Déconnectez puis reconnectez-vous.";
}
catch (Exception ex)
{
- this.SetErrorStatus($"Erreur lors du chargement des prestations: {ex.Message}");
+ StatusMessage = $"Erreur lors du chargement des prestations: {ex.Message}";
}
finally
{
@@ -83,19 +81,19 @@ public partial class BrushViewModel : RdvViewModel
{
if (!Consent)
{
- this.SetWarningStatus("Le consentement est requis pour poster la commande.");
+ StatusMessage = "Le consentement est requis pour poster la commande.";
return;
}
if (string.IsNullOrWhiteSpace(Address))
{
- this.SetWarningStatus("L'adresse du rendez-vous est requise.");
+ StatusMessage = "L'adresse du rendez-vous est requise.";
return;
}
if (SelectedPrestation is null)
{
- this.SetWarningStatus("Sélectionnez une prestation coiffure.");
+ StatusMessage = "Sélectionnez une prestation coiffure.";
return;
}
@@ -145,18 +143,18 @@ public partial class BrushViewModel : RdvViewModel
}).ConfigureAwait(true);
}
- this.SetInfoStatus(IsEditingExisting
+ StatusMessage = IsEditingExisting
? $"Commande #{ExistingQueryId} mise à jour sur {BillingRoute} pour {Performer.UserName}."
- : $"Commande transmise sur {BillingRoute} pour {Performer.UserName}.");
+ : $"Commande transmise sur {BillingRoute} pour {Performer.UserName}.";
}
catch (HttpRequestException ex)
when (ex.StatusCode is HttpStatusCode.Unauthorized or HttpStatusCode.Forbidden)
{
- this.SetWarningStatus("Accès refusé au billing (scope 'api'). Déconnectez puis reconnectez-vous.");
+ StatusMessage = "Accès refusé au billing (scope 'api'). Déconnectez puis reconnectez-vous.";
}
catch (Exception ex)
{
- this.SetErrorStatus($"Erreur lors de l'envoi de la commande: {ex.Message}");
+ StatusMessage = $"Erreur lors de l'envoi de la commande: {ex.Message}";
}
finally
{
diff --git a/src/PostIt/PostIt/ViewModels/Commands/MBrushViewModel.cs b/src/PostIt/PostIt/ViewModels/Commands/MBrushViewModel.cs
index 05481c2c3..793a77516 100644
--- a/src/PostIt/PostIt/ViewModels/Commands/MBrushViewModel.cs
+++ b/src/PostIt/PostIt/ViewModels/Commands/MBrushViewModel.cs
@@ -49,20 +49,20 @@ public partial class MBrushViewModel : BrushViewModel
{
if (!Consent)
{
- this.SetWarningStatus("Le consentement est requis pour poster la commande.");
+ StatusMessage = "Le consentement est requis pour poster la commande.";
return;
}
if (string.IsNullOrWhiteSpace(Address))
{
- this.SetWarningStatus("L'adresse du rendez-vous est requise.");
+ StatusMessage = "L'adresse du rendez-vous est requise.";
return;
}
var selectedPrestations = MultiPrestations.Where(x => x.IsSelected).ToList();
if (selectedPrestations.Count == 0)
{
- this.SetWarningStatus("Sélectionnez au moins une prestation coiffure.");
+ StatusMessage = "Sélectionnez au moins une prestation coiffure.";
return;
}
@@ -109,18 +109,18 @@ public partial class MBrushViewModel : BrushViewModel
}).ConfigureAwait(true);
}
- this.SetInfoStatus(IsEditingExisting
+ StatusMessage = IsEditingExisting
? $"Commande #{ExistingQueryId} mise à jour sur {BillingRoute} pour {Performer.UserName}."
- : $"Commande transmise sur {BillingRoute} pour {Performer.UserName}.");
+ : $"Commande transmise sur {BillingRoute} pour {Performer.UserName}.";
}
catch (HttpRequestException ex)
when (ex.StatusCode is HttpStatusCode.Unauthorized or HttpStatusCode.Forbidden)
{
- this.SetWarningStatus("Accès refusé au billing (scope 'api'). Déconnectez puis reconnectez-vous.");
+ StatusMessage = "Accès refusé au billing (scope 'api'). Déconnectez puis reconnectez-vous.";
}
catch (Exception ex)
{
- this.SetErrorStatus($"Erreur lors de l'envoi de la commande: {ex.Message}");
+ StatusMessage = $"Erreur lors de l'envoi de la commande: {ex.Message}";
}
finally
{
diff --git a/src/PostIt/PostIt/ViewModels/Commands/RdvViewModel.cs b/src/PostIt/PostIt/ViewModels/Commands/RdvViewModel.cs
index 7a7d17df6..c2ff3294e 100644
--- a/src/PostIt/PostIt/ViewModels/Commands/RdvViewModel.cs
+++ b/src/PostIt/PostIt/ViewModels/Commands/RdvViewModel.cs
@@ -17,12 +17,6 @@ public partial class RdvViewModel : BillingCommandPageViewModel
[ObservableProperty]
public partial string Address { get; set; } = string.Empty;
- [ObservableProperty]
- public partial string SuggestedAddress { get; set; } = string.Empty;
-
- [ObservableProperty]
- public partial bool IsResolvingAddress { get; set; }
-
[ObservableProperty]
public partial double? Latitude { get; set; }
@@ -33,27 +27,12 @@ public partial class RdvViewModel : BillingCommandPageViewModel
[ObservableProperty]
public partial DateTime EventDate { get; set; }
- public DateTimeOffset? EventDateSelection
- {
- get => new(EventDate);
- set
- {
- if (!value.HasValue)
- return;
-
- EventDate = value.Value.LocalDateTime;
- }
- }
-
public RdvViewModel(ActivityInfo activity, ActivityUserDisplayItem performer, CommandFormSummary form, BillingApiClient billingClient)
: base(activity, performer, form, billingClient)
{
EventDate = DateTime.Now.AddDays(1);
}
- public bool HasSuggestedAddress => !string.IsNullOrWhiteSpace(SuggestedAddress);
- public bool HasSuggestedAddressPanel => HasSuggestedAddress || IsResolvingAddress;
-
protected override void ApplyExistingQuery(BillingQueryDetailsDto existingQuery)
{
ExistingQueryId = existingQuery.Id;
@@ -71,12 +50,11 @@ public partial class RdvViewModel : BillingCommandPageViewModel
if (existingQuery.Location is not null)
{
Address = existingQuery.Location.Address ?? string.Empty;
- SuggestedAddress = string.Empty;
Latitude = existingQuery.Location.Latitude;
Longitude = existingQuery.Location.Longitude;
}
- this.SetInfoStatus($"Commande #{existingQuery.Id} chargée.");
+ StatusMessage = $"Commande #{existingQuery.Id} chargée.";
}
[RelayCommand(CanExecute = nameof(CanUseCurrentLocation))]
@@ -93,23 +71,23 @@ public partial class RdvViewModel : BillingCommandPageViewModel
var result = await Platform.TryGetCurrentLocationAsync(default).ConfigureAwait(true);
if (!result.IsSuccess || !result.Latitude.HasValue || !result.Longitude.HasValue)
{
- this.SetWarningStatus(result.Message);
+ StatusMessage = result.Message;
return;
}
Latitude = result.Latitude.Value;
Longitude = result.Longitude.Value;
- this.SetInfoStatus(string.IsNullOrWhiteSpace(Address)
+ StatusMessage = string.IsNullOrWhiteSpace(Address)
? "Position récupérée. Complétez l'adresse puis envoyez la commande."
- : result.Message);
+ : result.Message;
}
catch (OperationCanceledException)
{
- this.SetWarningStatus("La récupération de la position a été annulée.");
+ StatusMessage = "La récupération de la position a été annulée.";
}
catch (Exception ex)
{
- this.SetErrorStatus($"Impossible de récupérer la position: {ex.Message}");
+ StatusMessage = $"Impossible de récupérer la position: {ex.Message}";
}
finally
{
@@ -135,119 +113,31 @@ public partial class RdvViewModel : BillingCommandPageViewModel
};
}
- public void ApplyLocationFromMap(double latitude, double longitude)
- {
- Latitude = Math.Round(latitude, 6);
- Longitude = Math.Round(longitude, 6);
-
- if (string.IsNullOrWhiteSpace(Address))
- {
- this.SetInfoStatus("Position sélectionnée sur la carte. Complétez l'adresse puis envoyez la commande.");
- return;
- }
-
- this.SetInfoStatus("Position sélectionnée sur la carte.");
- }
-
- public void NotifyReverseGeocodingStarted()
- {
- IsResolvingAddress = true;
- this.SetInfoStatus(string.IsNullOrWhiteSpace(Address)
- ? "Recherche de l'adresse depuis la carte..."
- : "Recherche d'une adresse suggérée..."
- );
- }
-
- public void NotifyReverseGeocodingUnavailable()
- {
- IsResolvingAddress = false;
- if (HasSuggestedAddress || !string.IsNullOrWhiteSpace(Address))
- return;
-
- this.SetInfoStatus("Position sélectionnée sur la carte. Complétez l'adresse puis envoyez la commande.");
- }
-
- public void ApplyResolvedAddress(string address)
- {
- if (string.IsNullOrWhiteSpace(address))
- return;
-
- var trimmedAddress = address.Trim();
- if (string.IsNullOrWhiteSpace(Address))
- {
- Address = trimmedAddress;
- SuggestedAddress = string.Empty;
- IsResolvingAddress = false;
- this.SetInfoStatus("Adresse mise à jour depuis la carte.");
- return;
- }
-
- if (string.Equals(Address.Trim(), trimmedAddress, StringComparison.Ordinal))
- {
- SuggestedAddress = string.Empty;
- IsResolvingAddress = false;
- return;
- }
-
- SuggestedAddress = trimmedAddress;
- IsResolvingAddress = false;
- this.SetInfoStatus("Adresse suggérée depuis la carte. Appliquez-la si besoin.");
- }
-
- [RelayCommand(CanExecute = nameof(HasSuggestedAddress))]
- private void ApplySuggestedAddress()
- {
- if (string.IsNullOrWhiteSpace(SuggestedAddress))
- return;
-
- Address = SuggestedAddress.Trim();
- SuggestedAddress = string.Empty;
- IsResolvingAddress = false;
- this.SetInfoStatus("Adresse suggérée appliquée.");
- }
-
- partial void OnSuggestedAddressChanged(string value)
- {
- OnPropertyChanged(nameof(HasSuggestedAddress));
- OnPropertyChanged(nameof(HasSuggestedAddressPanel));
- ApplySuggestedAddressCommand.NotifyCanExecuteChanged();
- }
-
- partial void OnIsResolvingAddressChanged(bool value)
- {
- OnPropertyChanged(nameof(HasSuggestedAddressPanel));
- }
-
- partial void OnEventDateChanged(DateTime value)
- {
- OnPropertyChanged(nameof(EventDateSelection));
- }
-
protected override async Task SubmitAsync()
{
if (!IsSupported)
{
- this.SetWarningStatus(SupportMessage);
+ StatusMessage = SupportMessage;
return;
}
if (!Consent)
{
- this.SetWarningStatus("Le consentement est requis pour poster la commande.");
+ StatusMessage = "Le consentement est requis pour poster la commande.";
return;
}
if (string.IsNullOrWhiteSpace(Address))
{
- this.SetWarningStatus("L'adresse du rendez-vous est requise.");
+ StatusMessage = "L'adresse du rendez-vous est requise.";
return;
}
if (string.IsNullOrWhiteSpace(Reason))
{
- this.SetWarningStatus("Le motif du rendez-vous est requis.");
+ StatusMessage = "Le motif du rendez-vous est requis.";
return;
}
@@ -296,17 +186,17 @@ public partial class RdvViewModel : BillingCommandPageViewModel
}).ConfigureAwait(true);
}
- this.SetInfoStatus(IsEditingExisting
+ StatusMessage = IsEditingExisting
? $"Commande #{ExistingQueryId} mise à jour sur {BillingRoute} pour {Performer.UserName}."
- : $"Commande transmise sur {BillingRoute} pour {Performer.UserName}.");
+ : $"Commande transmise sur {BillingRoute} pour {Performer.UserName}.";
}
catch (HttpRequestException ex) when (ex.StatusCode is HttpStatusCode.Unauthorized or HttpStatusCode.Forbidden)
{
- this.SetWarningStatus("Accès refusé au billing (scope 'api'). Déconnectez puis reconnectez-vous.");
+ StatusMessage = "Accès refusé au billing (scope 'api'). Déconnectez puis reconnectez-vous.";
}
catch (Exception ex)
{
- this.SetErrorStatus($"Erreur lors de l'envoi: {ex.Message}");
+ StatusMessage = $"Erreur lors de l'envoi: {ex.Message}";
}
finally
{
diff --git a/src/PostIt/PostIt/ViewModels/MainViewModel.cs b/src/PostIt/PostIt/ViewModels/MainViewModel.cs
index d2667c012..f56b666dd 100644
--- a/src/PostIt/PostIt/ViewModels/MainViewModel.cs
+++ b/src/PostIt/PostIt/ViewModels/MainViewModel.cs
@@ -12,7 +12,7 @@ using PostIt.Helpers;
namespace PostIt.ViewModels;
-public partial class MainViewModel : ViewModelBase, IActionStatusViewModel
+public partial class MainViewModel : ViewModelBase
{
/// Window/tab title. Cosmetic — bound by
/// MainPage.axaml if at all. Not the post title.
@@ -54,9 +54,6 @@ public partial class MainViewModel : ViewModelBase, IActionStatusViewModel
[ObservableProperty]
public partial string StatusMessage { get; set; }
- [ObservableProperty]
- public partial StatusNotice ActionStatus { get; set; } = StatusNotice.Info("Pret.");
-
[ObservableProperty]
public partial string SearchText { get; set; }
@@ -87,7 +84,7 @@ public partial class MainViewModel : ViewModelBase, IActionStatusViewModel
Posts.Add(post);
}
ApplyFilter();
- this.SetInfoStatus($"{Posts.Count} billet(s) chargé(s).");
+ StatusMessage = $"Loaded {Posts.Count} posts.";
});
}
@@ -107,7 +104,7 @@ public partial class MainViewModel : ViewModelBase, IActionStatusViewModel
// than to send a request the server will reject.
if (string.IsNullOrWhiteSpace(DraftTitle))
{
- this.SetWarningStatus("Le titre est obligatoire.");
+ StatusMessage = "Title is required.";
return;
}
@@ -137,7 +134,7 @@ public partial class MainViewModel : ViewModelBase, IActionStatusViewModel
if (created is not null)
{
SelectedPost = created;
- this.SetInfoStatus($"Billet {created.Id} créé.");
+ StatusMessage = $"Created post {created.Id}.";
}
}
else
@@ -153,7 +150,7 @@ public partial class MainViewModel : ViewModelBase, IActionStatusViewModel
DateModified = DateTime.UtcNow,
};
await BlogClient!.UpdatePostAsync(SelectedPost.Id, update);
- this.SetInfoStatus($"Billet {SelectedPost.Id} enregistré.");
+ StatusMessage = $"Saved post {SelectedPost.Id}.";
}
await RefreshPostsAsync();
@@ -165,14 +162,14 @@ public partial class MainViewModel : ViewModelBase, IActionStatusViewModel
{
if (SelectedPost is null || SelectedPost.Id == 0)
{
- this.SetWarningStatus("Sélectionnez un billet existant avant suppression.");
+ StatusMessage = "Select an existing post before deleting.";
return;
}
await ExecuteAsync(async () =>
{
await BlogClient!.DeletePostAsync(SelectedPost.Id);
- this.SetInfoStatus($"Billet {SelectedPost.Id} supprimé.");
+ StatusMessage = $"Deleted post {SelectedPost.Id}.";
SelectedPost = null;
await RefreshPostsAsync();
});
@@ -197,7 +194,7 @@ public partial class MainViewModel : ViewModelBase, IActionStatusViewModel
{
if (SelectedPost is null || SelectedPost.Id == 0)
{
- this.SetWarningStatus("Sélectionnez un billet existant pour changer sa publication.");
+ StatusMessage = "Sélectionnez un billet existant pour changer sa publication.";
return;
}
@@ -214,9 +211,9 @@ public partial class MainViewModel : ViewModelBase, IActionStatusViewModel
// locally flipped state until the round-trip
// re-hydrates it.
SelectedPost.IsPublished = publish;
- this.SetInfoStatus(publish
+ StatusMessage = publish
? $"Billet {SelectedPost.Id} publié."
- : $"Billet {SelectedPost.Id} remis en brouillon.");
+ : $"Billet {SelectedPost.Id} remis en brouillon.";
});
}
@@ -250,7 +247,7 @@ public partial class MainViewModel : ViewModelBase, IActionStatusViewModel
{
if (SelectedPost is null)
{
- this.SetWarningStatus("Sélectionnez un billet existant avant de gérer l'ACL.");
+ StatusMessage = "Select an existing post before managing ACL.";
return;
}
@@ -349,7 +346,7 @@ public partial class MainViewModel : ViewModelBase, IActionStatusViewModel
FilteredPosts = new ObservableCollection();
SelectedPost = null;
IsBusy = false;
- this.SetInfoStatus("Prêt.");
+ StatusMessage = "Ready";
Settings = settings ?? new Settings();
SearchText = Settings.SearchText;
WindowTitle = "PostIt";
@@ -479,12 +476,12 @@ public partial class MainViewModel : ViewModelBase, IActionStatusViewModel
try
{
IsBusy = true;
- this.SetInfoStatus("Traitement en cours...");
+ StatusMessage = "Working...";
await action();
}
catch (Exception ex)
{
- this.SetErrorStatus($"Erreur: {ex.Message}");
+ StatusMessage = $"Error: {ex.Message}";
}
finally
{
diff --git a/src/PostIt/PostIt/ViewModels/PostAclDialogViewModel.cs b/src/PostIt/PostIt/ViewModels/PostAclDialogViewModel.cs
index be1b220fa..605446068 100644
--- a/src/PostIt/PostIt/ViewModels/PostAclDialogViewModel.cs
+++ b/src/PostIt/PostIt/ViewModels/PostAclDialogViewModel.cs
@@ -37,7 +37,7 @@ public sealed class PostAclEntry
/// any 403 / 404 will surface as an exception caught by the
/// command and routed to .
///
-public partial class PostAclDialogViewModel : ViewModelBase, IActionStatusViewModel
+public partial class PostAclDialogViewModel : ViewModelBase
{
private readonly BlogAclApiClient _aclClient;
private readonly CircleApiClient _circleClient;
@@ -61,10 +61,7 @@ public partial class PostAclDialogViewModel : ViewModelBase, IActionStatusViewMo
public partial bool IsBusy { get; set; }
[ObservableProperty]
- public partial string StatusMessage { get; set; } = "Pret.";
-
- [ObservableProperty]
- public partial StatusNotice ActionStatus { get; set; } = StatusNotice.Info("Pret.");
+ public partial string StatusMessage { get; set; } = string.Empty;
///
/// Idempotency gate for : the dialog
@@ -118,12 +115,12 @@ public partial class PostAclDialogViewModel : ViewModelBase, IActionStatusViewMo
AclEntries = new ObservableCollection(AclEntries.Select(a => ToAclEntry(a.CircleId)));
- this.SetInfoStatus($"{AclEntries.Count} autorisation(s)");
+ StatusMessage = $"{AclEntries.Count} autorisation(s)";
_loaded = true;
}
catch (Exception ex)
{
- this.SetErrorStatus($"Erreur: {ex.Message}");
+ StatusMessage = $"Erreur: {ex.Message}";
}
finally
{
@@ -136,7 +133,7 @@ public partial class PostAclDialogViewModel : ViewModelBase, IActionStatusViewMo
{
if (SelectedCircleToAdd is null)
{
- this.SetWarningStatus("Sélectionnez un cercle à ajouter");
+ StatusMessage = "Sélectionnez un cercle à ajouter";
return;
}
@@ -145,7 +142,7 @@ public partial class PostAclDialogViewModel : ViewModelBase, IActionStatusViewMo
{
if (AclEntries.Any(a => a.CircleId == SelectedCircleToAdd.Id))
{
- this.SetWarningStatus($"Cercle « {SelectedCircleToAdd.Name} » déjà autorisé");
+ StatusMessage = $"Cercle « {SelectedCircleToAdd.Name} » déjà autorisé";
return;
}
@@ -157,11 +154,11 @@ public partial class PostAclDialogViewModel : ViewModelBase, IActionStatusViewMo
if (created is not null)
{
AclEntries.Add(ToAclEntry(created.CircleId));
- this.SetInfoStatus($"Cercle « {SelectedCircleToAdd.Name} » autorisé");
+ StatusMessage = $"Cercle « {SelectedCircleToAdd.Name} » autorisé";
}
else
{
- this.SetWarningStatus("Autorisation refusée par le serveur");
+ StatusMessage = "Autorisation refusée par le serveur";
}
}
catch (HttpRequestException ex) when (ex.StatusCode == HttpStatusCode.Conflict)
@@ -169,11 +166,11 @@ public partial class PostAclDialogViewModel : ViewModelBase, IActionStatusViewMo
// Conflict means the link already exists in backend. Resync
// from the dedicated ACL API so the UI reflects server truth.
await ReloadAclEntriesFromServerAsync();
- this.SetWarningStatus($"Cercle « {SelectedCircleToAdd.Name} » déjà autorisé");
+ StatusMessage = $"Cercle « {SelectedCircleToAdd.Name} » déjà autorisé";
}
catch (Exception ex)
{
- this.SetErrorStatus($"Erreur: {ex.Message}");
+ StatusMessage = $"Erreur: {ex.Message}";
}
finally
{
@@ -192,11 +189,11 @@ public partial class PostAclDialogViewModel : ViewModelBase, IActionStatusViewMo
var existing = AclEntries.FirstOrDefault(e => e.CircleId == acl.CircleId);
if (existing is not null)
AclEntries.Remove(existing);
- this.SetInfoStatus("Autorisation révoquée");
+ StatusMessage = "Autorisation révoquée";
}
catch (Exception ex)
{
- this.SetErrorStatus($"Erreur: {ex.Message}");
+ StatusMessage = $"Erreur: {ex.Message}";
}
finally
{
diff --git a/src/PostIt/PostIt/ViewModels/Settings/Settings.cs b/src/PostIt/PostIt/ViewModels/Settings/Settings.cs
index 0864c1416..e63f0b321 100644
--- a/src/PostIt/PostIt/ViewModels/Settings/Settings.cs
+++ b/src/PostIt/PostIt/ViewModels/Settings/Settings.cs
@@ -7,7 +7,6 @@ using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Text.Json;
-using System.Text.Json.Serialization;
[assembly: InternalsVisibleTo("PostIt.Tests")]
@@ -32,20 +31,6 @@ public partial class Settings : ViewModelBase
[ObservableProperty]
public partial string SearchText { get; set; } = string.Empty;
- [ObservableProperty]
- [JsonIgnore]
- public partial StatusNotice ActionStatus { get; set; } = StatusNotice.Info("Pret.");
-
- public void SetActionStatus(string message, StatusSeverity severity = StatusSeverity.Info)
- {
- ActionStatus = severity switch
- {
- StatusSeverity.Error => StatusNotice.Error(message),
- StatusSeverity.Warning => StatusNotice.Warning(message),
- _ => StatusNotice.Info(message),
- };
- }
-
///
/// Catch top-level mutations: the four ObservableProperty
/// setters above all funnel through here, and we flip
@@ -125,8 +110,6 @@ public partial class Settings : ViewModelBase
// build options from a torn read.
lock (_mutationGate)
{
- EnsureAuthenticationDefaultsLocked();
-
var options = new OidcClientOptions
{
Authority = Authentication.Authority,
@@ -155,25 +138,6 @@ public partial class Settings : ViewModelBase
}
}
- private void EnsureAuthenticationDefaultsLocked()
- {
- Authentication ??= new AuthenticationSettings();
-
- if (string.IsNullOrWhiteSpace(Authentication.Authority))
- Authentication.Authority = AuthenticationSettings.DefaultAuthority;
-
- if (string.IsNullOrWhiteSpace(Authentication.ClientId))
- Authentication.ClientId = AuthenticationSettings.DefaultClientId;
-
- if (string.IsNullOrWhiteSpace(Authentication.RedirectUri))
- Authentication.RedirectUri = AuthenticationSettings.DesktopRedirectUri;
-
- if (Authentication.Scopes is null || Authentication.Scopes.Length == 0)
- Authentication.Scopes = AuthenticationSettings.DefaultScopes;
-
- Authentication.RefreshScopeListText();
- }
-
///
/// Scopes the PostIt client always requires from the OIDC provider,
/// regardless of what the user has in their settings file.
@@ -357,13 +321,11 @@ public partial class Settings : ViewModelBase
AuthenticationSettings.DesktopRedirectUri : settings.Authentication.RedirectUri;
if (settings.Authentication.Scopes is null || settings.Authentication.Scopes.Length == 0)
{
- this.Authentication.Scopes = AuthenticationSettings.DefaultScopes;
+ settings.Authentication.Scopes = AuthenticationSettings.DefaultScopes;
}
else
this.Authentication.Scopes = settings.Authentication.Scopes;
}
-
- EnsureAuthenticationDefaultsLocked();
}
// A disk load (or an embedded-resource fallback) is the
// baseline, not a user edit. Clear the dirty flag last
@@ -444,8 +406,6 @@ public partial class Settings : ViewModelBase
[RelayCommand(CanExecute = nameof(CanSave))]
public void Save()
{
- SetActionStatus("Enregistrement des parametres...", StatusSeverity.Info);
-
var configDir = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
"PostIt");
@@ -465,13 +425,10 @@ public partial class Settings : ViewModelBase
File.SetUnixFileMode(configPath,
UnixFileMode.UserRead | UnixFileMode.UserWrite);
IsDirty = false;
- SetActionStatus("Parametres sauvegardes.", StatusSeverity.Info);
-
Console.WriteLine($"💾 Settings saved to {configPath}");
}
catch (Exception ex)
{
- SetActionStatus($"Echec sauvegarde parametres: {ex.Message}", StatusSeverity.Error);
Console.Error.WriteLine($"🩎 Error saving settings to {configPath}: {ex.Message}");
throw;
}
diff --git a/src/PostIt/PostIt/ViewModels/SignaturePageViewModel.cs b/src/PostIt/PostIt/ViewModels/SignaturePageViewModel.cs
index 23ba70cf9..b4b37974b 100644
--- a/src/PostIt/PostIt/ViewModels/SignaturePageViewModel.cs
+++ b/src/PostIt/PostIt/ViewModels/SignaturePageViewModel.cs
@@ -30,7 +30,7 @@ namespace PostIt.ViewModels;
/// until the Yavsc.Org endpoint exists; the contract there will
/// be POST /api/signature/{devisId} with this same payload.
///
-public partial class SignaturePageViewModel : ViewModelBase, IActionStatusViewModel
+public partial class SignaturePageViewModel : ViewModelBase
{
///
/// Default capture surface, in DIPs. 3:1 ratio matches a
@@ -42,9 +42,6 @@ public partial class SignaturePageViewModel : ViewModelBase, IActionStatusViewMo
[ObservableProperty]
public partial string StatusMessage { get; set; } = "Prêt.";
- [ObservableProperty]
- public partial StatusNotice ActionStatus { get; set; } = StatusNotice.Info("Prêt.");
-
[ObservableProperty]
public partial int StrokeCount { get; set; }
@@ -110,7 +107,7 @@ public partial class SignaturePageViewModel : ViewModelBase, IActionStatusViewMo
private void OnStrokeCompleted(object? sender, SignaturePadData data)
{
- this.SetInfoStatus($"Trait terminé. {data.StrokeCount} trait(s).");
+ StatusMessage = $"Trait terminé. {data.StrokeCount} trait(s).";
RefreshCounts();
}
@@ -128,7 +125,7 @@ public partial class SignaturePageViewModel : ViewModelBase, IActionStatusViewMo
public void Clear()
{
_control?.Clear();
- this.SetInfoStatus("Effacé.");
+ StatusMessage = "Effacé.";
RefreshCounts();
}
@@ -137,14 +134,14 @@ public partial class SignaturePageViewModel : ViewModelBase, IActionStatusViewMo
{
if (_control is null)
{
- this.SetWarningStatus("Contrôle non attaché.");
+ StatusMessage = "Contrôle non attaché.";
return;
}
var data = _control.Snapshot();
if (data.IsEmpty)
{
- this.SetWarningStatus("Rien à capturer.");
+ StatusMessage = "Rien à capturer.";
return;
}
@@ -152,11 +149,11 @@ public partial class SignaturePageViewModel : ViewModelBase, IActionStatusViewMo
{
var path = WriteCapture(data);
LastCapturedPath = path;
- this.SetInfoStatus($"Capture enregistrée: {path}");
+ StatusMessage = $"Capture enregistrée: {path}";
}
catch (Exception ex)
{
- this.SetErrorStatus($"Erreur: {ex.Message}");
+ StatusMessage = $"Erreur: {ex.Message}";
}
await Task.CompletedTask;
}
diff --git a/src/PostIt/PostIt/ViewModels/StatusNotice.cs b/src/PostIt/PostIt/ViewModels/StatusNotice.cs
deleted file mode 100644
index 972c64350..000000000
--- a/src/PostIt/PostIt/ViewModels/StatusNotice.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-namespace PostIt.ViewModels;
-
-public enum StatusSeverity
-{
- Info,
- Warning,
- Error
-}
-
-public sealed class StatusNotice
-{
- public string Message { get; }
- public StatusSeverity Severity { get; }
- public string Glyph { get; }
- public string Background { get; }
- public string BorderBrush { get; }
- public string Foreground { get; }
-
- private StatusNotice(string message, StatusSeverity severity)
- {
- Message = string.IsNullOrWhiteSpace(message) ? "Pret." : message;
- Severity = severity;
-
- (Glyph, Background, BorderBrush, Foreground) = severity switch
- {
- StatusSeverity.Error => ("!", "#FDECEA", "#C62828", "#7F1D1D"),
- StatusSeverity.Warning => ("~", "#FFF8E1", "#E6A700", "#7C4A03"),
- _ => ("i", "#E8F0FE", "#5B8DEF", "#1E3A8A"),
- };
- }
-
- public static StatusNotice Info(string message) => new(message, StatusSeverity.Info);
- public static StatusNotice Warning(string message) => new(message, StatusSeverity.Warning);
- public static StatusNotice Error(string message) => new(message, StatusSeverity.Error);
-}
diff --git a/src/PostIt/PostIt/Views/ActivitiesPage.axaml b/src/PostIt/PostIt/Views/ActivitiesPage.axaml
index a34d8edf2..16d883443 100644
--- a/src/PostIt/PostIt/Views/ActivitiesPage.axaml
+++ b/src/PostIt/PostIt/Views/ActivitiesPage.axaml
@@ -1,7 +1,6 @@
-
+
diff --git a/src/PostIt/PostIt/Views/AddCircleMemberDialog.axaml b/src/PostIt/PostIt/Views/AddCircleMemberDialog.axaml
index a17f8574e..8b2329886 100644
--- a/src/PostIt/PostIt/Views/AddCircleMemberDialog.axaml
+++ b/src/PostIt/PostIt/Views/AddCircleMemberDialog.axaml
@@ -3,7 +3,6 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="PostIt.Views.AddCircleMemberDialog"
xmlns:vm="using:PostIt.ViewModels"
- xmlns:postitControls="using:PostIt.Controls"
xmlns:services="using:PostIt.Services"
x:DataType="vm:AddCircleMemberDialogViewModel"
>
@@ -48,8 +47,8 @@
-
+
public AddCircleMemberDialogViewModel? ViewModel
=> DataContext as AddCircleMemberDialogViewModel;
+
+ private async Task OnCloseClicked(object? sender, RoutedEventArgs e)
+ {
+ App app = App.Current! as App;
+ await app!.GoBackAsync();
+ }
}
diff --git a/src/PostIt/PostIt/Views/BillingQueriesPage.axaml b/src/PostIt/PostIt/Views/BillingQueriesPage.axaml
index 52b255129..c4b333e42 100644
--- a/src/PostIt/PostIt/Views/BillingQueriesPage.axaml
+++ b/src/PostIt/PostIt/Views/BillingQueriesPage.axaml
@@ -1,89 +1,51 @@
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
+
+
diff --git a/src/PostIt/PostIt/Views/BillingQueryDetailsPage.axaml b/src/PostIt/PostIt/Views/BillingQueryDetailsPage.axaml
deleted file mode 100644
index 82231ad83..000000000
--- a/src/PostIt/PostIt/Views/BillingQueryDetailsPage.axaml
+++ /dev/null
@@ -1,131 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/PostIt/PostIt/Views/BillingQueryDetailsPage.axaml.cs b/src/PostIt/PostIt/Views/BillingQueryDetailsPage.axaml.cs
deleted file mode 100644
index ed5336ee0..000000000
--- a/src/PostIt/PostIt/Views/BillingQueryDetailsPage.axaml.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using Avalonia.Controls;
-using Avalonia.Markup.Xaml;
-
-namespace PostIt.Views;
-
-public partial class BillingQueryDetailsPage : ContentPage
-{
- public BillingQueryDetailsPage()
- {
- InitializeComponent();
- }
-
- private void InitializeComponent()
- {
- AvaloniaXamlLoader.Load(this);
- }
-}
diff --git a/src/PostIt/PostIt/Views/CirclesPage.axaml b/src/PostIt/PostIt/Views/CirclesPage.axaml
index 8488201e2..6fc2172ba 100644
--- a/src/PostIt/PostIt/Views/CirclesPage.axaml
+++ b/src/PostIt/PostIt/Views/CirclesPage.axaml
@@ -1,7 +1,6 @@
-
+
diff --git a/src/PostIt/PostIt/Views/CommandFormsPage.axaml b/src/PostIt/PostIt/Views/CommandFormsPage.axaml
index f44c098bd..8fad010ef 100644
--- a/src/PostIt/PostIt/Views/CommandFormsPage.axaml
+++ b/src/PostIt/PostIt/Views/CommandFormsPage.axaml
@@ -1,7 +1,6 @@
-
+
diff --git a/src/PostIt/PostIt/Views/Commands/BrushPage.axaml b/src/PostIt/PostIt/Views/Commands/BrushPage.axaml
index d01ea4a1b..9c33cecb2 100644
--- a/src/PostIt/PostIt/Views/Commands/BrushPage.axaml
+++ b/src/PostIt/PostIt/Views/Commands/BrushPage.axaml
@@ -3,7 +3,6 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:cvm="using:PostIt.ViewModels.Commands"
- xmlns:postitControls="using:PostIt.Controls"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="PostIt.Views.Commands.BrushPage"
@@ -94,8 +93,16 @@
Content="{Binding SubmitLabel}"
Command="{Binding SubmitCommand}"
IsEnabled="{Binding IsSupported}" />
-
+
-
+
-
+
-
-
-
-
-
+
-
-
-
-
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
+
-
+
("LocationMap");
- if (_locationMap is null)
- return;
-
- var map = new Map();
- map.Layers.Add(OpenStreetMap.CreateTileLayer());
- _selectionLayer = CreateSelectionLayer();
- map.Layers.Add(_selectionLayer);
- _locationMap.Map = map;
- _locationMap.MapTapped += OnMapTapped;
-
- DataContextChanged += OnDataContextChanged;
- AttachViewModel(DataContext as RdvViewModel);
- }
-
- private void OnDataContextChanged(object? sender, System.EventArgs e)
- {
- AttachViewModel(DataContext as RdvViewModel);
- CenterFromViewModel();
- }
-
- private async void OnMapTapped(object? sender, MapEventArgs e)
- {
- if (DataContext is not RdvViewModel vm)
- return;
-
- var (longitude, latitude) = SphericalMercator.ToLonLat(e.WorldPosition.X, e.WorldPosition.Y);
- vm.ApplyLocationFromMap(latitude, longitude);
- UpdateMarkerFromViewModel();
- CenterMap(latitude, longitude, zoomLevel: SelectedZoomLevel);
- await TryResolveAddressAsync(vm, latitude, longitude);
- }
-
- private async void OnCenterCurrentLocationClicked(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
- {
- if (DataContext is not RdvViewModel vm || !vm.CanUseCurrentLocation)
- return;
-
- await vm.UseCurrentLocationCommand.ExecuteAsync(null);
- UpdateMarkerFromViewModel();
- CenterFromViewModel();
-
- if (vm.Latitude.HasValue && vm.Longitude.HasValue)
- await TryResolveAddressAsync(vm, vm.Latitude.Value, vm.Longitude.Value);
- }
-
- private void AttachViewModel(RdvViewModel? vm)
- {
- if (_currentViewModel is not null)
- _currentViewModel.PropertyChanged -= OnViewModelPropertyChanged;
-
- _currentViewModel = vm;
-
- if (_currentViewModel is not null)
- _currentViewModel.PropertyChanged += OnViewModelPropertyChanged;
-
- UpdateMarkerFromViewModel();
- }
-
- private void OnViewModelPropertyChanged(object? sender, PropertyChangedEventArgs e)
- {
- if (e.PropertyName == nameof(RdvViewModel.Latitude)
- || e.PropertyName == nameof(RdvViewModel.Longitude))
- {
- UpdateMarkerFromViewModel();
- }
- }
-
- private void CenterFromViewModel()
- {
- if (DataContext is not RdvViewModel vm)
- {
- CenterMap(DefaultLatitude, DefaultLongitude, zoomLevel: DefaultZoomLevel);
- return;
- }
-
- if (vm.Latitude.HasValue && vm.Longitude.HasValue)
- {
- CenterMap(vm.Latitude.Value, vm.Longitude.Value, zoomLevel: SelectedZoomLevel);
- return;
- }
-
- CenterMap(DefaultLatitude, DefaultLongitude, zoomLevel: DefaultZoomLevel);
- }
-
- private void CenterMap(double latitude, double longitude, int zoomLevel)
- {
- if (_locationMap?.Map is null)
- return;
-
- var (x, y) = SphericalMercator.FromLonLat(longitude, latitude);
- _locationMap.Map.Navigator.CenterOn(x, y);
- _locationMap.Map.Navigator.ZoomToLevel(zoomLevel);
- }
-
- private void UpdateMarkerFromViewModel()
- {
- if (_selectionLayer is null)
- return;
-
- if (DataContext is not RdvViewModel vm
- || !vm.Latitude.HasValue
- || !vm.Longitude.HasValue)
- {
- _selectionLayer.Features = Enumerable.Empty();
- _locationMap?.RefreshData(ChangeType.Discrete);
- return;
- }
-
- var (x, y) = SphericalMercator.FromLonLat(vm.Longitude.Value, vm.Latitude.Value);
- _selectionLayer.Features = new IFeature[] { new PointFeature(x, y) };
- _locationMap?.RefreshData(ChangeType.Discrete);
- }
-
- private static MemoryLayer CreateSelectionLayer()
- {
- return new MemoryLayer("selected-location")
- {
- Style = new SymbolStyle
- {
- SymbolType = SymbolType.Ellipse,
- Fill = new Brush(Color.Crimson),
- Outline = new Pen(Color.White, 2),
- SymbolScale = 0.9,
- },
- Features = Enumerable.Empty(),
- };
- }
-
- private async Task TryResolveAddressAsync(RdvViewModel vm, double latitude, double longitude)
- {
- if (_lastResolvedLatitude.HasValue
- && _lastResolvedLongitude.HasValue
- && AreCoordinatesClose(_lastResolvedLatitude.Value, _lastResolvedLongitude.Value, latitude, longitude)
- && !string.IsNullOrWhiteSpace(_lastResolvedAddress))
- {
- vm.ApplyResolvedAddress(_lastResolvedAddress);
- return;
- }
-
- _reverseGeocodeCts?.Cancel();
- _reverseGeocodeCts?.Dispose();
- _reverseGeocodeCts = new CancellationTokenSource();
- var cancellationToken = _reverseGeocodeCts.Token;
-
- try
- {
- vm.NotifyReverseGeocodingStarted();
- await Task.Delay(ReverseGeocodingDebounce, cancellationToken).ConfigureAwait(true);
-
- var resolved = await _reverseGeocodingService
- .TryResolveAddressAsync(latitude, longitude, cancellationToken)
- .ConfigureAwait(true);
-
- if (!string.IsNullOrWhiteSpace(resolved))
- {
- _lastResolvedLatitude = latitude;
- _lastResolvedLongitude = longitude;
- _lastResolvedAddress = resolved;
- vm.ApplyResolvedAddress(resolved);
- return;
- }
-
- vm.NotifyReverseGeocodingUnavailable();
- }
- catch (OperationCanceledException)
- {
- vm.IsResolvingAddress = false;
- }
- }
-
- internal static bool AreCoordinatesClose(
- double latitudeA,
- double longitudeA,
- double latitudeB,
- double longitudeB)
- {
- return Math.Abs(latitudeA - latitudeB) <= ReverseGeocodingCacheToleranceDegrees
- && Math.Abs(longitudeA - longitudeB) <= ReverseGeocodingCacheToleranceDegrees;
- }
}
diff --git a/src/PostIt/PostIt/Views/MainPage.axaml b/src/PostIt/PostIt/Views/MainPage.axaml
index 871a2f541..41ed7ece3 100644
--- a/src/PostIt/PostIt/Views/MainPage.axaml
+++ b/src/PostIt/PostIt/Views/MainPage.axaml
@@ -3,7 +3,6 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="using:PostIt.ViewModels"
- xmlns:postitControls="using:PostIt.Controls"
xmlns:models="using:Yavsc.Blogspot"
xmlns:views="using:PostIt.Views"
xmlns:AvaloniaEdit="clr-namespace:AvaloniaEdit;assembly=AvaloniaEdit"
@@ -105,8 +104,7 @@
VerticalAlignment="Stretch">
-
+
diff --git a/src/PostIt/PostIt/Views/PostAclDialog.axaml b/src/PostIt/PostIt/Views/PostAclDialog.axaml
index 4af8c018e..8552988e5 100644
--- a/src/PostIt/PostIt/Views/PostAclDialog.axaml
+++ b/src/PostIt/PostIt/Views/PostAclDialog.axaml
@@ -3,7 +3,6 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="PostIt.Views.PostAclDialog"
xmlns:vm="using:PostIt.ViewModels"
- xmlns:postitControls="using:PostIt.Controls"
xmlns:dtos="using:Yavsc.Api.Client.Dtos"
x:DataType="vm:PostAclDialogViewModel"
>
@@ -54,8 +53,8 @@
-
+
diff --git a/src/PostIt/PostIt/Views/SettingsPage.axaml b/src/PostIt/PostIt/Views/SettingsPage.axaml
index 2973679b5..611b89954 100644
--- a/src/PostIt/PostIt/Views/SettingsPage.axaml
+++ b/src/PostIt/PostIt/Views/SettingsPage.axaml
@@ -2,7 +2,6 @@
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="cl:avalonia.Controls"
- xmlns:postitControls="using:PostIt.Controls"
x:Class="PostIt.Views.SettingsPage"
xmlns:vm="using:PostIt.ViewModels"
x:DataType="vm:Settings"
@@ -52,7 +51,9 @@
Opacity="0.8"
TextWrapping="Wrap" />
-
+
-
+
diff --git a/src/PostIt/PostIt/Views/SettingsPage.axaml.cs b/src/PostIt/PostIt/Views/SettingsPage.axaml.cs
index b50245919..593dcfeeb 100644
--- a/src/PostIt/PostIt/Views/SettingsPage.axaml.cs
+++ b/src/PostIt/PostIt/Views/SettingsPage.axaml.cs
@@ -6,10 +6,10 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Avalonia.Controls;
+using Avalonia.Media;
using Avalonia.Platform.Storage;
using Microsoft.Extensions.DependencyInjection;
using PostIt.Services;
-using PostIt.ViewModels;
namespace PostIt.Views;
public partial class SettingsPage: ContentPage
@@ -28,12 +28,12 @@ public partial class SettingsPage: ContentPage
{
var statusVersion = Interlocked.Increment(ref _avatarStatusVersion);
ChooseAvatarButton.IsEnabled = false;
- SetAvatarStatus("Selection d'un fichier avatar...", StatusSeverity.Info);
+ SetAvatarStatus("Sélection d'un fichier avatar...", Brushes.Gray);
var topLevel = TopLevel.GetTopLevel(this);
if (topLevel is null)
{
- SetAvatarStatus("Impossible d'acceder a la fenetre active.", StatusSeverity.Error);
+ SetAvatarStatus("Impossible d'accéder à la fenêtre active.", Brushes.IndianRed);
ChooseAvatarButton.IsEnabled = true;
return;
}
@@ -54,28 +54,27 @@ public partial class SettingsPage: ContentPage
var file = files.FirstOrDefault();
if (file is null)
{
- SetAvatarStatus("Upload annule.", StatusSeverity.Warning);
+ SetAvatarStatus("Upload annulé.", Brushes.Gray);
ChooseAvatarButton.IsEnabled = true;
return;
}
try
{
- SetAvatarStatus("Upload avatar en cours...", StatusSeverity.Info);
+ SetAvatarStatus("Upload avatar en cours...", Brushes.Gray);
await using var stream = await file.OpenReadAsync();
var api = ((App)App.Current!).ServiceProvider!.GetRequiredService();
var message = await api.SetAvatarAsync(stream, file.Name, GetMimeType(file.Name));
SetAvatarStatus(string.IsNullOrWhiteSpace(message)
- ? "Avatar mis a jour."
- : message,
- StatusSeverity.Info);
+ ? "Avatar mis à jour."
+ : message, Brushes.ForestGreen);
_ = ClearSuccessStatusLaterAsync(statusVersion);
}
catch (Exception ex)
{
- SetAvatarStatus($"Echec upload avatar: {ex.Message}", StatusSeverity.Error);
+ SetAvatarStatus($"Échec upload avatar: {ex.Message}", Brushes.IndianRed);
Console.Error.WriteLine($"🩎 Avatar upload failed: {ex.Message}");
}
finally
@@ -90,15 +89,16 @@ public partial class SettingsPage: ContentPage
if (statusVersion != _avatarStatusVersion)
return;
- SetAvatarStatus($"Avatar pret. Formats supportes: {AcceptedAvatarFormats}. Taille max: {MaxAvatarSizeMegabytes} MB.", StatusSeverity.Info);
+ if (AvatarUploadStatusText.Foreground == Brushes.ForestGreen)
+ {
+ SetAvatarStatus($"Avatar prêt. Formats supportés: {AcceptedAvatarFormats}. Taille max: {MaxAvatarSizeMegabytes} MB.", Brushes.Gray);
+ }
}
- private void SetAvatarStatus(string message, StatusSeverity severity)
+ private void SetAvatarStatus(string message, IBrush color)
{
- if (DataContext is Settings settings)
- {
- settings.SetActionStatus(message, severity);
- }
+ AvatarUploadStatusText.Foreground = color;
+ AvatarUploadStatusText.Text = message;
}
private static string GetMimeType(string fileName)
diff --git a/src/PostIt/PostIt/Views/SignaturePage.axaml b/src/PostIt/PostIt/Views/SignaturePage.axaml
index 021208b54..d868f2a48 100644
--- a/src/PostIt/PostIt/Views/SignaturePage.axaml
+++ b/src/PostIt/PostIt/Views/SignaturePage.axaml
@@ -3,7 +3,6 @@
xmlns:d="http://github.com/avaloniaui/avalonia"
xmlns:vm="using:PostIt.ViewModels"
xmlns:controls="using:PostIt.Controls"
- xmlns:postitControls="using:PostIt.Controls"
x:Class="PostIt.Views.SignaturePage"
x:DataType="vm:SignaturePageViewModel"
HorizontalAlignment="Stretch"
@@ -60,8 +59,10 @@
-
+
diff --git a/src/Yavsc.Abstract/Blogspot/BlogPostDto.cs b/src/Yavsc.Abstract/Blogspot/BlogPostDto.cs
index bdb2ccdc8..9cb5b1430 100644
--- a/src/Yavsc.Abstract/Blogspot/BlogPostDto.cs
+++ b/src/Yavsc.Abstract/Blogspot/BlogPostDto.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using Yavsc.Abstract.Identity.Security;
using System.Text.Json.Serialization;
diff --git a/src/Yavsc.Abstract/Blogspot/IBlogPost.cs b/src/Yavsc.Abstract/Blogspot/IBlogPost.cs
index 38a50b78f..1ef371803 100644
--- a/src/Yavsc.Abstract/Blogspot/IBlogPost.cs
+++ b/src/Yavsc.Abstract/Blogspot/IBlogPost.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
diff --git a/src/Yavsc.Abstract/Chat/ChatHubConstants.cs b/src/Yavsc.Abstract/Chat/ChatHubConstants.cs
index c673e6fae..b54c00c74 100644
--- a/src/Yavsc.Abstract/Chat/ChatHubConstants.cs
+++ b/src/Yavsc.Abstract/Chat/ChatHubConstants.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
namespace Yavsc.Abstract.Chat
{
public static class ChatHubConstants
diff --git a/src/Yavsc.Abstract/Chat/IChatRoom.cs b/src/Yavsc.Abstract/Chat/IChatRoom.cs
index 133ca2837..1d6f68dd5 100644
--- a/src/Yavsc.Abstract/Chat/IChatRoom.cs
+++ b/src/Yavsc.Abstract/Chat/IChatRoom.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using System.ComponentModel.DataAnnotations;
namespace Yavsc.Abstract.Chat
diff --git a/src/Yavsc.Abstract/FileSystem/AbstractFileSystemHelpers.cs b/src/Yavsc.Abstract/FileSystem/AbstractFileSystemHelpers.cs
index 14bc86435..dd805864e 100644
--- a/src/Yavsc.Abstract/FileSystem/AbstractFileSystemHelpers.cs
+++ b/src/Yavsc.Abstract/FileSystem/AbstractFileSystemHelpers.cs
@@ -1,6 +1,4 @@
-#nullable enable annotations
-
-using System.Text;
+using System.Text;
using Yavsc.ViewModels.UserFiles;
namespace Yavsc.Server.Helpers
diff --git a/src/Yavsc.Abstract/FileSystem/FsOperationInfo.cs b/src/Yavsc.Abstract/FileSystem/FsOperationInfo.cs
index 0e3c0e0c7..76a481492 100644
--- a/src/Yavsc.Abstract/FileSystem/FsOperationInfo.cs
+++ b/src/Yavsc.Abstract/FileSystem/FsOperationInfo.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
namespace Yavsc.Abstract.Helpers
{
public enum ErrorCode {
diff --git a/src/Yavsc.Abstract/FileSystem/UserDirectoryInfo.cs b/src/Yavsc.Abstract/FileSystem/UserDirectoryInfo.cs
index 2ec5dcfaf..fa727d0c0 100644
--- a/src/Yavsc.Abstract/FileSystem/UserDirectoryInfo.cs
+++ b/src/Yavsc.Abstract/FileSystem/UserDirectoryInfo.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using Yavsc.Server.Helpers;
namespace Yavsc.ViewModels.UserFiles
diff --git a/src/Yavsc.Abstract/Google/GDate.cs b/src/Yavsc.Abstract/Google/GDate.cs
index 10e4de92e..3506ba416 100644
--- a/src/Yavsc.Abstract/Google/GDate.cs
+++ b/src/Yavsc.Abstract/Google/GDate.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
//
// GDate.cs
//
diff --git a/src/Yavsc.Abstract/Google/Messaging/MessageWithPayloadResponse.cs b/src/Yavsc.Abstract/Google/Messaging/MessageWithPayloadResponse.cs
index 980a4abcf..59538ca62 100644
--- a/src/Yavsc.Abstract/Google/Messaging/MessageWithPayloadResponse.cs
+++ b/src/Yavsc.Abstract/Google/Messaging/MessageWithPayloadResponse.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
//
// MessageWithPayloadResponse.cs
//
diff --git a/src/Yavsc.Abstract/IT/Fixing/Bug.cs b/src/Yavsc.Abstract/IT/Fixing/Bug.cs
index 60bd155f6..f0b403bb7 100644
--- a/src/Yavsc.Abstract/IT/Fixing/Bug.cs
+++ b/src/Yavsc.Abstract/IT/Fixing/Bug.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Yavsc.Attributes.Validation;
diff --git a/src/Yavsc.Abstract/Identity/IApplicationUser.cs b/src/Yavsc.Abstract/Identity/IApplicationUser.cs
index 0b8e1047c..5d1d5b1ca 100644
--- a/src/Yavsc.Abstract/Identity/IApplicationUser.cs
+++ b/src/Yavsc.Abstract/Identity/IApplicationUser.cs
@@ -1,6 +1,4 @@
-#nullable enable annotations
-
-namespace Yavsc.Abstract.Identity
+namespace Yavsc.Abstract.Identity
{
public interface IApplicationUser
{
diff --git a/src/Yavsc.Abstract/Identity/UserDisplayHelpers.cs b/src/Yavsc.Abstract/Identity/UserDisplayHelpers.cs
index 4277d6e3b..242615527 100644
--- a/src/Yavsc.Abstract/Identity/UserDisplayHelpers.cs
+++ b/src/Yavsc.Abstract/Identity/UserDisplayHelpers.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
namespace Yavsc.Abstract.Identity
{
///
diff --git a/src/Yavsc.Abstract/Interfaces/Workflow/IBookQueryData.cs b/src/Yavsc.Abstract/Interfaces/Workflow/IBookQueryData.cs
index eb3dee591..2c844f925 100644
--- a/src/Yavsc.Abstract/Interfaces/Workflow/IBookQueryData.cs
+++ b/src/Yavsc.Abstract/Interfaces/Workflow/IBookQueryData.cs
@@ -1,6 +1,4 @@
-#nullable enable annotations
-
-using Yavsc.Abstract.Identity;
+using Yavsc.Abstract.Identity;
namespace Yavsc.Interfaces
{
diff --git a/src/Yavsc.Abstract/Messaging/Comment.cs b/src/Yavsc.Abstract/Messaging/Comment.cs
index d8eef456c..3b8702ae1 100644
--- a/src/Yavsc.Abstract/Messaging/Comment.cs
+++ b/src/Yavsc.Abstract/Messaging/Comment.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using Yavsc.Interfaces;
diff --git a/src/Yavsc.Abstract/Messaging/Notification.cs b/src/Yavsc.Abstract/Messaging/Notification.cs
index f7b35b48b..dbbf735d5 100644
--- a/src/Yavsc.Abstract/Messaging/Notification.cs
+++ b/src/Yavsc.Abstract/Messaging/Notification.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
diff --git a/src/Yavsc.Abstract/Messaging/RdvQueryEvent.cs b/src/Yavsc.Abstract/Messaging/RdvQueryEvent.cs
index 9e2ecb754..b2168bd7c 100644
--- a/src/Yavsc.Abstract/Messaging/RdvQueryEvent.cs
+++ b/src/Yavsc.Abstract/Messaging/RdvQueryEvent.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
//
// BookQueryEvent.cs
//
diff --git a/src/Yavsc.Abstract/Messaging/RdvQueryProviderInfo.cs b/src/Yavsc.Abstract/Messaging/RdvQueryProviderInfo.cs
index 94eeb5ab9..87125c544 100644
--- a/src/Yavsc.Abstract/Messaging/RdvQueryProviderInfo.cs
+++ b/src/Yavsc.Abstract/Messaging/RdvQueryProviderInfo.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using Yavsc.Abstract.Identity;
using Yavsc.Models.Relationship;
diff --git a/src/Yavsc.Abstract/Workflow/IMobileDeviceDeclaration.cs b/src/Yavsc.Abstract/Workflow/IMobileDeviceDeclaration.cs
index 7a1dbc261..6e55ebe51 100644
--- a/src/Yavsc.Abstract/Workflow/IMobileDeviceDeclaration.cs
+++ b/src/Yavsc.Abstract/Workflow/IMobileDeviceDeclaration.cs
@@ -1,6 +1,4 @@
-#nullable enable annotations
-
-// Copyright (C) 2016 Paul Schneider
+// Copyright (C) 2016 Paul Schneider
//
// This file is part of yavsc.
//
diff --git a/src/Yavsc.Abstract/Workflow/IPerformerProfile.cs b/src/Yavsc.Abstract/Workflow/IPerformerProfile.cs
index 606285a6c..4314dd371 100644
--- a/src/Yavsc.Abstract/Workflow/IPerformerProfile.cs
+++ b/src/Yavsc.Abstract/Workflow/IPerformerProfile.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
namespace Yavsc.Workflow
{
public interface IPerformerProfile
diff --git a/src/Yavsc.Abstract/Workflow/PerformerCodeInputValidation.cs b/src/Yavsc.Abstract/Workflow/PerformerCodeInputValidation.cs
index 4ed60e465..84e9c1cc7 100644
--- a/src/Yavsc.Abstract/Workflow/PerformerCodeInputValidation.cs
+++ b/src/Yavsc.Abstract/Workflow/PerformerCodeInputValidation.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
diff --git a/src/Yavsc.Api.Client/ActivityApiClient.cs b/src/Yavsc.Api.Client/ActivityApiClient.cs
index 8199de9d4..52fad1a49 100644
--- a/src/Yavsc.Api.Client/ActivityApiClient.cs
+++ b/src/Yavsc.Api.Client/ActivityApiClient.cs
@@ -19,29 +19,19 @@ public sealed class ActivityApiClient
private const string PathPrefix = "activity";
private readonly IYavscApiClient _api;
- private readonly Func _businessBaseAddress;
- private readonly Func _avatarBaseAddress;
+ private readonly Uri _baseAddress;
+ private readonly Uri _avatarBaseAddress;
public ActivityApiClient(IYavscApiClient api, string businessBaseAddress, string? avatarBaseAddress = null)
- : this(
- api,
- () => businessBaseAddress,
- () => avatarBaseAddress)
- {
- }
-
- public ActivityApiClient(
- IYavscApiClient api,
- Func businessBaseAddress,
- Func? avatarBaseAddress = null)
{
_api = api ?? throw new ArgumentNullException(nameof(api));
- _businessBaseAddress = businessBaseAddress ?? throw new ArgumentNullException(nameof(businessBaseAddress));
- _avatarBaseAddress = avatarBaseAddress ?? (() => null);
+ if (string.IsNullOrEmpty(businessBaseAddress))
+ throw new ArgumentException("Base address is required.", nameof(businessBaseAddress));
- // Validate initial values early to fail fast on invalid setup.
- _ = ResolveBusinessBaseAddress();
- _ = ResolveAvatarBaseAddress();
+ _baseAddress = new Uri(businessBaseAddress, UriKind.Absolute);
+ _avatarBaseAddress = string.IsNullOrWhiteSpace(avatarBaseAddress)
+ ? _baseAddress
+ : new Uri(avatarBaseAddress, UriKind.Absolute);
}
public Task> GetCatalogAsync(
@@ -75,7 +65,7 @@ public sealed class ActivityApiClient
public string BuildAvatarXsUrl(string? userName)
{
- var siteRoot = new Uri(ResolveAvatarBaseAddress(), "/");
+ var siteRoot = new Uri(_avatarBaseAddress, "/");
if (string.IsNullOrWhiteSpace(userName))
{
@@ -85,22 +75,5 @@ public sealed class ActivityApiClient
return new Uri(siteRoot, $"avatars/{Uri.EscapeDataString(userName)}.xs.png").ToString();
}
- private string Absolute(string relativePath) => new Uri(ResolveBusinessBaseAddress(), relativePath).ToString();
-
- private Uri ResolveBusinessBaseAddress()
- {
- var raw = _businessBaseAddress();
- if (string.IsNullOrWhiteSpace(raw))
- throw new InvalidOperationException("Business base address is required.");
-
- return new Uri(raw, UriKind.Absolute);
- }
-
- private Uri ResolveAvatarBaseAddress()
- {
- var raw = _avatarBaseAddress();
- return string.IsNullOrWhiteSpace(raw)
- ? ResolveBusinessBaseAddress()
- : new Uri(raw, UriKind.Absolute);
- }
+ private string Absolute(string relativePath) => new Uri(_baseAddress, relativePath).ToString();
}
diff --git a/src/Yavsc.Api.Client/BillingApiClient.cs b/src/Yavsc.Api.Client/BillingApiClient.cs
index c3a0be103..35a6722d5 100644
--- a/src/Yavsc.Api.Client/BillingApiClient.cs
+++ b/src/Yavsc.Api.Client/BillingApiClient.cs
@@ -20,20 +20,15 @@ public sealed class BillingApiClient
private const string PathPrefix = "billing";
private readonly IYavscApiClient _api;
- private readonly Func _businessBaseAddress;
+ private readonly Uri _baseAddress;
public BillingApiClient(IYavscApiClient api, string businessBaseAddress)
- : this(api, () => businessBaseAddress)
- {
- }
-
- public BillingApiClient(IYavscApiClient api, Func businessBaseAddress)
{
_api = api ?? throw new ArgumentNullException(nameof(api));
- _businessBaseAddress = businessBaseAddress ?? throw new ArgumentNullException(nameof(businessBaseAddress));
+ if (string.IsNullOrWhiteSpace(businessBaseAddress))
+ throw new ArgumentException("Base address is required.", nameof(businessBaseAddress));
- // Validate initial value early to fail fast on invalid setup.
- _ = ResolveBusinessBaseAddress();
+ _baseAddress = new Uri(businessBaseAddress, UriKind.Absolute);
}
public Task CreateAsync(string billingCode, object payload, CancellationToken ct = default)
@@ -126,16 +121,7 @@ public sealed class BillingApiClient
ct: ct);
}
- private string Absolute(string relativePath) => new Uri(ResolveBusinessBaseAddress(), relativePath).ToString();
-
- private Uri ResolveBusinessBaseAddress()
- {
- var raw = _businessBaseAddress();
- if (string.IsNullOrWhiteSpace(raw))
- throw new InvalidOperationException("Business base address is required.");
-
- return new Uri(raw, UriKind.Absolute);
- }
+ private string Absolute(string relativePath) => new Uri(_baseAddress, relativePath).ToString();
private static BillingQueryDetailsDto MapRdv(RdvQueryResponse dto, string billingCode)
{
diff --git a/src/Yavsc.Api.Test/Fixtures/ApiWebServerFixture.cs b/src/Yavsc.Api.Test/Fixtures/ApiWebServerFixture.cs
index e2a8b3376..ca4ae70f9 100644
--- a/src/Yavsc.Api.Test/Fixtures/ApiWebServerFixture.cs
+++ b/src/Yavsc.Api.Test/Fixtures/ApiWebServerFixture.cs
@@ -204,10 +204,6 @@ public sealed class ApiWebServerFixture : WebHostFixture
ClientId = "alice",
PerformerId = "alice",
Consent = true,
- UserCreated = "alice",
- UserModified = "alice",
- DateCreated = DateTime.UtcNow,
- DateModified = DateTime.UtcNow,
EventDate = DateTime.UtcNow.AddDays(1),
Location = location,
Reason = "Initial rendez-vous",
@@ -297,10 +293,6 @@ public sealed class ApiWebServerFixture : WebHostFixture
ClientId = "alice",
PerformerId = "alice",
Consent = true,
- UserCreated = "alice",
- UserModified = "alice",
- DateCreated = DateTime.UtcNow,
- DateModified = DateTime.UtcNow,
EventDate = DateTime.UtcNow.AddDays(3),
Location = location,
PrestationId = prestation1.Id,
@@ -316,10 +308,6 @@ public sealed class ApiWebServerFixture : WebHostFixture
ClientId = "alice",
PerformerId = "alice",
Consent = true,
- UserCreated = "alice",
- UserModified = "alice",
- DateCreated = DateTime.UtcNow,
- DateModified = DateTime.UtcNow,
EventDate = DateTime.UtcNow.AddDays(4),
Location = location,
Prestations = new List
diff --git a/src/Yavsc.Api.Test/FrontOfficeApiControllerTests.cs b/src/Yavsc.Api.Test/FrontOfficeApiControllerTests.cs
deleted file mode 100644
index 97ed2e61c..000000000
--- a/src/Yavsc.Api.Test/FrontOfficeApiControllerTests.cs
+++ /dev/null
@@ -1,62 +0,0 @@
-using System.Net;
-using System.Net.Http.Headers;
-using Microsoft.Extensions.DependencyInjection;
-using Yavsc.Api.Test.Fixtures;
-using Yavsc.Helpers;
-using Yavsc.Models;
-using Yavsc.Tests.Shared;
-
-namespace Yavsc.Api.Test;
-
-[Collection("Yavsc Api")]
-public sealed class FrontOfficeApiControllerTests : IClassFixture
-{
- private readonly ApiWebServerFixture _fixture;
-
- public FrontOfficeApiControllerTests(ApiWebServerFixture fixture)
- {
- _fixture = fixture;
- }
-
- private HttpClient NewClient(string subject = "alice", string scope = "api")
- {
- var handler = new HttpClientHandler
- {
- ServerCertificateCustomValidationCallback = (_, _, _, _) => true
- };
-
- var http = new HttpClient(handler)
- {
- BaseAddress = new Uri(_fixture.BaseAddress)
- };
- http.DefaultRequestHeaders.Authorization =
- new AuthenticationHeaderValue("Bearer", TestTokenIssuer.Issue(subject, scope));
- return http;
- }
-
- [Fact]
- public async Task Front_accept_query_updates_status_without_server_error()
- {
- WorkflowHelpers.ConfigureBillingService();
- _fixture.ResetAndSeedRdvQueryGraph();
-
- long queryId;
- using (var scope = _fixture.Services.CreateScope())
- {
- var db = scope.ServiceProvider.GetRequiredService();
- queryId = db.RdvQueries.Select(q => q.Id).Single();
- }
-
- using var http = NewClient();
- var response = await http.PostAsync($"/api/v1/front/query/accept?billingCode=Rdv&queryId={queryId}", content: null, TestContext.Current.CancellationToken);
- var body = await response.Content.ReadAsStringAsync(TestContext.Current.CancellationToken);
-
- Assert.True(response.StatusCode == HttpStatusCode.OK, $"Unexpected status {(int)response.StatusCode} ({response.StatusCode}): {body}");
-
- using var assertScope = _fixture.Services.CreateScope();
- var assertDb = assertScope.ServiceProvider.GetRequiredService();
- var updated = assertDb.RdvQueries.Single(q => q.Id == queryId);
-
- Assert.Equal(QueryStatus.Accepted, updated.Status);
- }
-}
diff --git a/src/Yavsc.Api.Test/RdvQueryApiControllerTests.cs b/src/Yavsc.Api.Test/RdvQueryApiControllerTests.cs
index 668814239..8fe7e959e 100644
--- a/src/Yavsc.Api.Test/RdvQueryApiControllerTests.cs
+++ b/src/Yavsc.Api.Test/RdvQueryApiControllerTests.cs
@@ -82,65 +82,4 @@ public sealed class RdvQueryApiControllerTests : IClassFixture(TestContext.Current.CancellationToken);
- Assert.NotNull(created);
- Assert.Equal("alice", created!.ClientId);
- }
-
- [Fact]
- public async Task PostQuery_accepts_local_datetime_and_persists_as_utc()
- {
- _fixture.ResetAndSeedRdvQueryGraph();
- using var http = NewClient(subject: "alice");
-
- var localEventDate = DateTime.Now.AddDays(2);
- var createPayload = new
- {
- ActivityCode = "dev",
- PerformerId = "alice",
- Consent = true,
- EventDate = localEventDate,
- Location = new
- {
- Address = "3 rue du Test",
- Latitude = 48.8568,
- Longitude = 2.3524,
- },
- Reason = "Rendez-vous date locale",
- Status = QueryStatus.Inserted,
- };
-
- var createResponse = await http.PostAsJsonAsync("/api/v1/billing/Rdv", createPayload, TestContext.Current.CancellationToken);
- Assert.Equal(HttpStatusCode.Created, createResponse.StatusCode);
-
- var created = await createResponse.Content.ReadFromJsonAsync(TestContext.Current.CancellationToken);
- Assert.NotNull(created);
- Assert.Equal(DateTimeKind.Utc, created!.EventDate.Kind);
- }
}
diff --git a/src/Yavsc.Api/Controllers/Business/ActivityApiController.cs b/src/Yavsc.Api/Controllers/Business/ActivityApiController.cs
index aef393868..a8d288063 100644
--- a/src/Yavsc.Api/Controllers/Business/ActivityApiController.cs
+++ b/src/Yavsc.Api/Controllers/Business/ActivityApiController.cs
@@ -51,14 +51,6 @@ namespace Yavsc.Controllers
.Distinct()
.ToArray();
- // Some providers are brittle when translating Contains over an
- // empty in-memory array. If there is no candidate activity code,
- // the catalog is empty by definition.
- if (codes.Length == 0)
- {
- return Ok(new List());
- }
-
var performerCounts = await (
from ua in _context.UserActivities.AsNoTracking()
where !string.IsNullOrWhiteSpace(ua.DoesCode) && codes.Contains(ua.DoesCode)
@@ -72,10 +64,10 @@ namespace Yavsc.Controllers
var filteredActivities = activities
.Where(a =>
- (TryGetPerformerCount(performerCounts, a.Code, out var ownCount) && ownCount > 0)
+ (performerCounts.TryGetValue(a.Code, out var ownCount) && ownCount > 0)
|| (a.Children ?? new List())
.Where(c => !c.Hidden)
- .Any(c => TryGetPerformerCount(performerCounts, c.Code, out var childCount) && childCount > 0))
+ .Any(c => performerCounts.TryGetValue(c.Code, out var childCount) && childCount > 0))
.ToList();
return Ok(filteredActivities.Select(a => ToBrowseItem(a, performerCounts)).ToList());
@@ -277,10 +269,10 @@ namespace Yavsc.Controllers
Code = activity.Code,
Name = activity.Name,
ParentCode = activity.ParentCode,
- Description = activity.Description ?? string.Empty,
+ Description = activity.Description,
Photo = activity.Photo,
Rate = activity.Rate,
- PerformerCount = TryGetPerformerCount(performerCounts, activity.Code, out var count) ? count : 0,
+ PerformerCount = performerCounts.TryGetValue(activity.Code, out var count) ? count : 0,
Forms = (activity.Forms ?? Enumerable.Empty())
.Select(f => new CommandFormSummary
{
@@ -291,17 +283,17 @@ namespace Yavsc.Controllers
.ToList(),
Children = (activity.Children ?? Enumerable.Empty())
.Where(c => !c.Hidden)
- .Where(c => TryGetPerformerCount(performerCounts, c.Code, out var childCount) && childCount > 0)
+ .Where(c => performerCounts.TryGetValue(c.Code, out var childCount) && childCount > 0)
.OrderByDescending(c => c.Rate)
.Select(c => new ActivityInfo
{
Code = c.Code,
Name = c.Name,
ParentCode = c.ParentCode,
- Description = c.Description ?? string.Empty,
+ Description = c.Description,
Photo = c.Photo,
Rate = c.Rate,
- PerformerCount = TryGetPerformerCount(performerCounts, c.Code, out var childCount) ? childCount : 0,
+ PerformerCount = performerCounts.TryGetValue(c.Code, out var childCount) ? childCount : 0,
Forms = (c.Forms ?? Enumerable.Empty())
.Select(f => new CommandFormSummary
{
@@ -314,19 +306,5 @@ namespace Yavsc.Controllers
.ToList(),
};
}
-
- private static bool TryGetPerformerCount(
- IReadOnlyDictionary performerCounts,
- string code,
- out int count)
- {
- if (string.IsNullOrWhiteSpace(code))
- {
- count = 0;
- return false;
- }
-
- return performerCounts.TryGetValue(code, out count);
- }
}
}
diff --git a/src/Yavsc.Api/Controllers/Business/FrontOfficeApiController.cs b/src/Yavsc.Api/Controllers/Business/FrontOfficeApiController.cs
index 3adac5b03..a4ecbf2f8 100644
--- a/src/Yavsc.Api/Controllers/Business/FrontOfficeApiController.cs
+++ b/src/Yavsc.Api/Controllers/Business/FrontOfficeApiController.cs
@@ -3,7 +3,6 @@ using Microsoft.AspNetCore.Mvc;
using Yavsc.Helpers;
using Yavsc.Models;
using Yavsc.Services;
-using Yavsc.Server.Helpers;
using Yavsc.ViewModels.FrontOffice;
namespace Yavsc.ApiControllers
@@ -16,10 +15,10 @@ namespace Yavsc.ApiControllers
private IBillingService billing;
- public FrontOfficeApiController(ApplicationDbContext context, IBillingService billing = null)
+ public FrontOfficeApiController(ApplicationDbContext context, IBillingService billing)
{
dbContext = context;
- this.billing = billing ?? new BillingService(context);
+ this.billing = billing;
}
[HttpGet("profiles/{actCode}")]
@@ -37,7 +36,7 @@ namespace Yavsc.ApiControllers
if (billing == null) return BadRequest();
billing.Status = QueryStatus.Rejected;
- dbContext.SaveChanges(User.GetUserId());
+ dbContext.SaveChanges();
return Ok();
}
@@ -49,7 +48,7 @@ namespace Yavsc.ApiControllers
var billing = BillingService.GetBillable(dbContext, billingCode, queryId);
if (billing == null) return BadRequest();
billing.Status = QueryStatus.Accepted;
- dbContext.SaveChanges(User.GetUserId());
+ dbContext.SaveChanges();
return Ok();
}
}
diff --git a/src/Yavsc.Api/Controllers/Business/HairCutQueryApiController.cs b/src/Yavsc.Api/Controllers/Business/HairCutQueryApiController.cs
index 7f445fdd9..6c7c1ba68 100644
--- a/src/Yavsc.Api/Controllers/Business/HairCutQueryApiController.cs
+++ b/src/Yavsc.Api/Controllers/Business/HairCutQueryApiController.cs
@@ -82,17 +82,19 @@ public class HairCutQueryApiController : Controller
public async Task PostQuery([FromBody] HairCutQuery query, CancellationToken cancellationToken)
{
var uid = User.GetUserId();
- query.ClientId = uid;
+ if (string.IsNullOrWhiteSpace(query.ClientId))
+ {
+ query.ClientId = uid;
+ }
- ModelState.Remove("Client");
ModelState.Remove("ClientId");
- ModelState.Remove("UserCreated");
- ModelState.Remove("UserModified");
- ModelState.Remove("SelectedProfile");
ModelState.Remove("Prestation");
- ModelState.Remove("PerformerProfile");
- ModelState.Remove("Context");
- ModelState.Remove("Regularization");
+
+ if (query.ClientId != uid && !User.IsInRole(Constants.AdminGroupName))
+ {
+ ModelState.AddModelError("ClientId", "You can only create your own HairCutQuery");
+ return BadRequest(ModelState);
+ }
query.Prestation = await _context.HairPrestation
.SingleOrDefaultAsync(p => p.Id == query.PrestationId, cancellationToken);
diff --git a/src/Yavsc.Api/Controllers/Business/HairMultiCutQueryApiController.cs b/src/Yavsc.Api/Controllers/Business/HairMultiCutQueryApiController.cs
index 3b33c4160..f850b3f41 100644
--- a/src/Yavsc.Api/Controllers/Business/HairMultiCutQueryApiController.cs
+++ b/src/Yavsc.Api/Controllers/Business/HairMultiCutQueryApiController.cs
@@ -89,16 +89,18 @@ public class HairMultiCutQueryApiController : Controller
public async Task PostQuery([FromBody] HairMultiCutQuery query, CancellationToken cancellationToken)
{
var uid = User.GetUserId();
- query.ClientId = uid;
+ if (string.IsNullOrWhiteSpace(query.ClientId))
+ {
+ query.ClientId = uid;
+ }
- ModelState.Remove("Client");
ModelState.Remove("ClientId");
- ModelState.Remove("UserCreated");
- ModelState.Remove("UserModified");
- ModelState.Remove("SelectedProfile");
- ModelState.Remove("PerformerProfile");
- ModelState.Remove("Context");
- ModelState.Remove("Regularization");
+
+ if (query.ClientId != uid && !User.IsInRole(Constants.AdminGroupName))
+ {
+ ModelState.AddModelError("ClientId", "You can only create your own HairMultiCutQuery");
+ return BadRequest(ModelState);
+ }
if (query.Prestations is null || query.Prestations.Count == 0)
{
diff --git a/src/Yavsc.Api/Controllers/Business/RdvQueryApiController.cs b/src/Yavsc.Api/Controllers/Business/RdvQueryApiController.cs
index 48e3be2e1..fcfac2b22 100644
--- a/src/Yavsc.Api/Controllers/Business/RdvQueryApiController.cs
+++ b/src/Yavsc.Api/Controllers/Business/RdvQueryApiController.cs
@@ -65,18 +65,18 @@ public class RdvQueryApiController : Controller
public async Task PostQuery([FromBody] RdvQuery query, CancellationToken cancellationToken)
{
var uid = User.GetUserId();
- // Security: the caller always posts for themselves.
- query.ClientId = uid;
- query.EventDate = EnsureUtc(query.EventDate);
+ if (string.IsNullOrWhiteSpace(query.ClientId))
+ {
+ query.ClientId = uid;
+ }
- ModelState.Remove("Client");
ModelState.Remove("ClientId");
- ModelState.Remove("UserCreated");
- ModelState.Remove("UserModified");
- ModelState.Remove("SelectedProfile");
- ModelState.Remove("PerformerProfile");
- ModelState.Remove("Context");
- ModelState.Remove("Regularization");
+
+ if (query.ClientId != uid && !User.IsInRole(Constants.AdminGroupName))
+ {
+ ModelState.AddModelError("ClientId", "You can only create your own RdvQuery");
+ return BadRequest(ModelState);
+ }
if (!ModelState.IsValid)
{
@@ -123,44 +123,23 @@ public class RdvQueryApiController : Controller
[HttpPut("{id}")]
public async Task PutQuery([FromRoute] long id, [FromBody] RdvQuery query, CancellationToken cancellationToken)
{
- var uid = User.GetUserId();
- var existing = await _context.RdvQueries
- .Include(q => q.Location)
- .SingleOrDefaultAsync(q => q.Id == id, cancellationToken);
-
- if (existing is null)
+ if (!ModelState.IsValid)
{
- return NotFound();
+ return BadRequest(ModelState);
}
- if (existing.ClientId != uid && !User.IsInRole(Constants.AdminGroupName))
+ if (id != query.Id)
+ {
+ return BadRequest();
+ }
+
+ var uid = User.GetUserId();
+ if (query.ClientId != uid && !User.IsInRole(Constants.AdminGroupName))
{
return Forbid();
}
- existing.ActivityCode = query.ActivityCode;
- existing.PerformerId = query.PerformerId;
- existing.Consent = query.Consent;
- existing.EventDate = EnsureUtc(query.EventDate);
- existing.LocationType = query.LocationType;
- existing.Reason = query.Reason;
- existing.Status = query.Status;
- existing.Provisional = query.Provisional;
-
- if (query.Location is not null)
- {
- var resolvedLocation = await _context.Locations.FirstOrDefaultAsync(
- x => x.Address == query.Location.Address
- && x.Longitude == query.Location.Longitude
- && x.Latitude == query.Location.Latitude,
- cancellationToken);
-
- existing.Location = resolvedLocation ?? query.Location;
- if (resolvedLocation is null)
- {
- _context.Attach(query.Location);
- }
- }
+ _context.Entry(query).State = EntityState.Modified;
try
{
@@ -207,14 +186,4 @@ public class RdvQueryApiController : Controller
{
return _context.RdvQueries.Any(e => e.Id == id);
}
-
- private static DateTime EnsureUtc(DateTime value)
- {
- return value.Kind switch
- {
- DateTimeKind.Utc => value,
- DateTimeKind.Local => value.ToUniversalTime(),
- _ => DateTime.SpecifyKind(value, DateTimeKind.Utc)
- };
- }
}
diff --git a/src/Yavsc.Blogs/Controllers/BlogApiController.cs b/src/Yavsc.Blogs/Controllers/BlogApiController.cs
index b757d711b..8c76f7eea 100644
--- a/src/Yavsc.Blogs/Controllers/BlogApiController.cs
+++ b/src/Yavsc.Blogs/Controllers/BlogApiController.cs
@@ -55,14 +55,6 @@ namespace Yavsc.Blogs.Controllers
[HttpPut("{id}")]
public async Task PutBlog(long id, [FromBody] Models.Blog.BlogPost blog)
{
- // These properties are server-managed or optional graph members and
- // should not block JSON payloads coming from API clients.
- ModelState.Remove(nameof(Models.Blog.BlogPost.Author));
- ModelState.Remove(nameof(Models.Blog.BlogPost.Tags));
- ModelState.Remove(nameof(Models.Blog.BlogPost.Comments));
- ModelState.Remove(nameof(Models.Blog.BlogPost.UserCreated));
- ModelState.Remove(nameof(Models.Blog.BlogPost.UserModified));
-
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
@@ -95,14 +87,6 @@ namespace Yavsc.Blogs.Controllers
[HttpPost]
public IActionResult PostBlog([FromBody] Models.Blog.BlogPost blog)
{
- // These properties are server-managed or optional graph members and
- // should not block JSON payloads coming from API clients.
- ModelState.Remove(nameof(Models.Blog.BlogPost.Author));
- ModelState.Remove(nameof(Models.Blog.BlogPost.Tags));
- ModelState.Remove(nameof(Models.Blog.BlogPost.Comments));
- ModelState.Remove(nameof(Models.Blog.BlogPost.UserCreated));
- ModelState.Remove(nameof(Models.Blog.BlogPost.UserModified));
-
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
diff --git a/src/Yavsc.Org/Controllers/Accounting/AccountController.cs b/src/Yavsc.Org/Controllers/Accounting/AccountController.cs
index 44927d461..77e0e32a4 100644
--- a/src/Yavsc.Org/Controllers/Accounting/AccountController.cs
+++ b/src/Yavsc.Org/Controllers/Accounting/AccountController.cs
@@ -467,25 +467,8 @@ IHtmlLocalizerFactory htmlLocalizerFactory,
if (ModelState.IsValid)
{
- var existingUser = await _userManager.FindByEmailAsync(model.Email);
- if (existingUser is not null)
- {
- ModelState.AddModelError(nameof(model.Email), _localizer["DuplicateEmail"]);
- return View(model);
- }
-
var user = new ApplicationUser { UserName = model.UserName, Email = model.Email };
- IdentityResult result;
- try
- {
- result = await _userManager.CreateAsync(user, model.Password);
- }
- catch (DbUpdateException ex) when (IsDuplicateEmailViolation(ex))
- {
- _logger.LogWarning(ex, "Registration rejected: duplicate email '{Email}'.", model.Email);
- ModelState.AddModelError(nameof(model.Email), _localizer["DuplicateEmail"]);
- return View(model);
- }
+ var result = await _userManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
_logger.LogInformation(3, "User created a new account with password.");
@@ -534,21 +517,6 @@ IHtmlLocalizerFactory htmlLocalizerFactory,
return View(model);
}
- private static bool IsDuplicateEmailViolation(Exception exception)
- {
- for (var current = exception; current is not null; current = current.InnerException)
- {
- if (current is PostgresException pg
- && pg.SqlState == PostgresErrorCodes.UniqueViolation
- && string.Equals(pg.ConstraintName, "AK_AspNetUsers_Email", StringComparison.Ordinal))
- {
- return true;
- }
- }
-
- return false;
- }
-
[Authorize, HttpPost, ValidateAntiForgeryToken]
public async Task SendConfirationEmail()
{
diff --git a/src/Yavsc.Org/Controllers/Communicating/CommentsController.cs b/src/Yavsc.Org/Controllers/Communicating/CommentsController.cs
index 02dda32a1..3690671c5 100644
--- a/src/Yavsc.Org/Controllers/Communicating/CommentsController.cs
+++ b/src/Yavsc.Org/Controllers/Communicating/CommentsController.cs
@@ -121,7 +121,6 @@ namespace Yavsc.Controllers
public async Task Create(Comment comment)
{
comment.UserCreated = User.GetUserId();
- comment.UserModified = comment.UserCreated;
// AuthorId/UserCreated is set server-side after model binding;
// remove the stale binding error so a valid authenticated POST
// does not fall into the invalid branch.
@@ -130,7 +129,7 @@ namespace Yavsc.Controllers
if (ModelState.IsValid)
{
_context.Comment.Add(comment);
- await _context.SaveChangesAsync(comment.UserCreated);
+ await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
ViewBag.ReceiverId = new SelectList(_context.BlogSpot, "Id", "Title", comment.ReceiverId);
diff --git a/src/Yavsc.Server/Config.cs b/src/Yavsc.Server/Config.cs
index e68546eff..5d2bcdffb 100644
--- a/src/Yavsc.Server/Config.cs
+++ b/src/Yavsc.Server/Config.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using IdentityServer8;
using IdentityServer8.Models;
diff --git a/src/Yavsc.Server/Constants.cs b/src/Yavsc.Server/Constants.cs
index 8859e5e69..4ded48eae 100644
--- a/src/Yavsc.Server/Constants.cs
+++ b/src/Yavsc.Server/Constants.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
namespace Yavsc.Server
{
diff --git a/src/Yavsc.Server/Exceptions/AuthorizationFailureException.cs b/src/Yavsc.Server/Exceptions/AuthorizationFailureException.cs
index 4a588dfd9..a3c5105ec 100644
--- a/src/Yavsc.Server/Exceptions/AuthorizationFailureException.cs
+++ b/src/Yavsc.Server/Exceptions/AuthorizationFailureException.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
namespace Yavsc.Server.Exceptions;
[Serializable]
diff --git a/src/Yavsc.Server/Exceptions/YavscInfrastructureException.cs b/src/Yavsc.Server/Exceptions/YavscInfrastructureException.cs
index 583872414..7888970c5 100644
--- a/src/Yavsc.Server/Exceptions/YavscInfrastructureException.cs
+++ b/src/Yavsc.Server/Exceptions/YavscInfrastructureException.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
namespace Yavsc.Services
{
[Serializable]
diff --git a/src/Yavsc.Server/Helpers/BillingHelpers.cs b/src/Yavsc.Server/Helpers/BillingHelpers.cs
index 789b85a96..c10a76155 100644
--- a/src/Yavsc.Server/Helpers/BillingHelpers.cs
+++ b/src/Yavsc.Server/Helpers/BillingHelpers.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using System.Globalization;
using Yavsc.Billing;
using Yavsc.Models.Billing;
diff --git a/src/Yavsc.Server/Helpers/EstimateSignatureFileHelper.cs b/src/Yavsc.Server/Helpers/EstimateSignatureFileHelper.cs
index 8545c3a0a..e2d40266d 100644
--- a/src/Yavsc.Server/Helpers/EstimateSignatureFileHelper.cs
+++ b/src/Yavsc.Server/Helpers/EstimateSignatureFileHelper.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using System.Security.Claims;
using System.Text;
using System.Text.Json;
diff --git a/src/Yavsc.Server/Helpers/FileSystemHelpers.cs b/src/Yavsc.Server/Helpers/FileSystemHelpers.cs
index 29ada6b77..7d9d86ed0 100644
--- a/src/Yavsc.Server/Helpers/FileSystemHelpers.cs
+++ b/src/Yavsc.Server/Helpers/FileSystemHelpers.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using System.Security.Claims;
diff --git a/src/Yavsc.Server/Helpers/HtmlHelpers.cs b/src/Yavsc.Server/Helpers/HtmlHelpers.cs
index c23f05cd2..213ea369a 100644
--- a/src/Yavsc.Server/Helpers/HtmlHelpers.cs
+++ b/src/Yavsc.Server/Helpers/HtmlHelpers.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Http;
using Yavsc.Models.Drawing;
diff --git a/src/Yavsc.Server/Helpers/PayPalHelpers.cs b/src/Yavsc.Server/Helpers/PayPalHelpers.cs
index 51902c784..9d4074d46 100644
--- a/src/Yavsc.Server/Helpers/PayPalHelpers.cs
+++ b/src/Yavsc.Server/Helpers/PayPalHelpers.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using Microsoft.Extensions.Logging;
using Yavsc.Models.Billing;
using Microsoft.AspNetCore.Http;
diff --git a/src/Yavsc.Server/Helpers/RequestHelper.cs b/src/Yavsc.Server/Helpers/RequestHelper.cs
index 6b85a5c31..99fe15248 100644
--- a/src/Yavsc.Server/Helpers/RequestHelper.cs
+++ b/src/Yavsc.Server/Helpers/RequestHelper.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using System.Net;
using System.Net.Http.Headers;
using Yavsc.Server.Model;
diff --git a/src/Yavsc.Server/Helpers/ServiceExtensions.cs b/src/Yavsc.Server/Helpers/ServiceExtensions.cs
index 1a69ca42f..06e877be8 100644
--- a/src/Yavsc.Server/Helpers/ServiceExtensions.cs
+++ b/src/Yavsc.Server/Helpers/ServiceExtensions.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Extensions.Configuration;
diff --git a/src/Yavsc.Server/Helpers/UserHelpers.cs b/src/Yavsc.Server/Helpers/UserHelpers.cs
index f0a30995f..c3ee708d6 100644
--- a/src/Yavsc.Server/Helpers/UserHelpers.cs
+++ b/src/Yavsc.Server/Helpers/UserHelpers.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using Microsoft.EntityFrameworkCore;
using System.Security.Claims;
using Yavsc.Models;
diff --git a/src/Yavsc.Server/Hubs/ChatHub.cs b/src/Yavsc.Server/Hubs/ChatHub.cs
index 799f7441c..4a99b507c 100644
--- a/src/Yavsc.Server/Hubs/ChatHub.cs
+++ b/src/Yavsc.Server/Hubs/ChatHub.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
//
// ChatHub.cs
//
diff --git a/src/Yavsc.Server/Hubs/HubInputValidator.cs b/src/Yavsc.Server/Hubs/HubInputValidator.cs
index a2382c11e..a6acac5ac 100644
--- a/src/Yavsc.Server/Hubs/HubInputValidator.cs
+++ b/src/Yavsc.Server/Hubs/HubInputValidator.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
//
// ChatHub.cs
//
diff --git a/src/Yavsc.Server/Models/Access/GrantViewModel.cs b/src/Yavsc.Server/Models/Access/GrantViewModel.cs
index d0d379caa..d9d0e1562 100644
--- a/src/Yavsc.Server/Models/Access/GrantViewModel.cs
+++ b/src/Yavsc.Server/Models/Access/GrantViewModel.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
diff --git a/src/Yavsc.Server/Models/ApplicationDbContext.cs b/src/Yavsc.Server/Models/ApplicationDbContext.cs
index ade093c15..cb08023a3 100644
--- a/src/Yavsc.Server/Models/ApplicationDbContext.cs
+++ b/src/Yavsc.Server/Models/ApplicationDbContext.cs
@@ -108,7 +108,6 @@ namespace Yavsc.Models
;
builder.Entity().Property(a => a.ParentCode).IsRequired(false);
- builder.Entity().Property(a => a.Description).IsRequired(false);
builder.Entity().HasKey(c => c.Code);
builder.Entity()
diff --git a/src/Yavsc.Server/Models/ApplicationUser.cs b/src/Yavsc.Server/Models/ApplicationUser.cs
index 69fbf1e52..355e0ad15 100644
--- a/src/Yavsc.Server/Models/ApplicationUser.cs
+++ b/src/Yavsc.Server/Models/ApplicationUser.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Newtonsoft.Json;
diff --git a/src/Yavsc.Server/Models/Auth/DeviceDeclaration.cs b/src/Yavsc.Server/Models/Auth/DeviceDeclaration.cs
index 7ed5e9b0d..1db1d89e0 100644
--- a/src/Yavsc.Server/Models/Auth/DeviceDeclaration.cs
+++ b/src/Yavsc.Server/Models/Auth/DeviceDeclaration.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Newtonsoft.Json;
diff --git a/src/Yavsc.Server/Models/Bank/BankIdentity.cs b/src/Yavsc.Server/Models/Bank/BankIdentity.cs
index 092059acc..eea65d691 100644
--- a/src/Yavsc.Server/Models/Bank/BankIdentity.cs
+++ b/src/Yavsc.Server/Models/Bank/BankIdentity.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
diff --git a/src/Yavsc.Server/Models/Billing/Estimate.cs b/src/Yavsc.Server/Models/Billing/Estimate.cs
index 24cd021a8..e6495a140 100644
--- a/src/Yavsc.Server/Models/Billing/Estimate.cs
+++ b/src/Yavsc.Server/Models/Billing/Estimate.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
diff --git a/src/Yavsc.Server/Models/Billing/NominativeServiceCommand.cs b/src/Yavsc.Server/Models/Billing/NominativeServiceCommand.cs
index aa9e06abf..ad651d368 100644
--- a/src/Yavsc.Server/Models/Billing/NominativeServiceCommand.cs
+++ b/src/Yavsc.Server/Models/Billing/NominativeServiceCommand.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
diff --git a/src/Yavsc.Server/Models/Billing/histoestim.cs b/src/Yavsc.Server/Models/Billing/histoestim.cs
index df2860f5d..1f9b99f1f 100644
--- a/src/Yavsc.Server/Models/Billing/histoestim.cs
+++ b/src/Yavsc.Server/Models/Billing/histoestim.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
namespace Yavsc.Models.Billing
{
public partial class histoestim
diff --git a/src/Yavsc.Server/Models/Blog/BlogPost.cs b/src/Yavsc.Server/Models/Blog/BlogPost.cs
index 6dc8ff750..4c2f2ae5c 100644
--- a/src/Yavsc.Server/Models/Blog/BlogPost.cs
+++ b/src/Yavsc.Server/Models/Blog/BlogPost.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Newtonsoft.Json;
diff --git a/src/Yavsc.Server/Models/Blog/Comment.cs b/src/Yavsc.Server/Models/Blog/Comment.cs
index 5d7cc2912..4d39d0c2e 100644
--- a/src/Yavsc.Server/Models/Blog/Comment.cs
+++ b/src/Yavsc.Server/Models/Blog/Comment.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Newtonsoft.Json;
diff --git a/src/Yavsc.Server/Models/Calendar/Period.cs b/src/Yavsc.Server/Models/Calendar/Period.cs
index f333235b1..dfc285cf3 100644
--- a/src/Yavsc.Server/Models/Calendar/Period.cs
+++ b/src/Yavsc.Server/Models/Calendar/Period.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
//
// Period.cs
//
diff --git a/src/Yavsc.Server/Models/ErrorViewModel.cs b/src/Yavsc.Server/Models/ErrorViewModel.cs
index 087aa505b..178194769 100644
--- a/src/Yavsc.Server/Models/ErrorViewModel.cs
+++ b/src/Yavsc.Server/Models/ErrorViewModel.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
namespace Yavsc.Models;
public class ErrorViewModel
diff --git a/src/Yavsc.Server/Models/HairCut/BrusherProfile.cs b/src/Yavsc.Server/Models/HairCut/BrusherProfile.cs
index d89a56fa8..ba47bfdce 100644
--- a/src/Yavsc.Server/Models/HairCut/BrusherProfile.cs
+++ b/src/Yavsc.Server/Models/HairCut/BrusherProfile.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
//
// BrusherProfile.cs
diff --git a/src/Yavsc.Server/Models/HairCut/HairCutPaymentEvent.cs b/src/Yavsc.Server/Models/HairCut/HairCutPaymentEvent.cs
index 2c96a7d80..353249288 100644
--- a/src/Yavsc.Server/Models/HairCut/HairCutPaymentEvent.cs
+++ b/src/Yavsc.Server/Models/HairCut/HairCutPaymentEvent.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using Microsoft.Extensions.Localization;
using Yavsc.Interfaces.Workflow;
diff --git a/src/Yavsc.Server/Models/HairCut/HairCutQuery.cs b/src/Yavsc.Server/Models/HairCut/HairCutQuery.cs
index 680cf6956..0960db6d6 100644
--- a/src/Yavsc.Server/Models/HairCut/HairCutQuery.cs
+++ b/src/Yavsc.Server/Models/HairCut/HairCutQuery.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Yavsc.Models.Billing;
diff --git a/src/Yavsc.Server/Models/HairCut/HairCutQueryEvent.cs b/src/Yavsc.Server/Models/HairCut/HairCutQueryEvent.cs
index fadc353a8..bd30fb784 100644
--- a/src/Yavsc.Server/Models/HairCut/HairCutQueryEvent.cs
+++ b/src/Yavsc.Server/Models/HairCut/HairCutQueryEvent.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using Yavsc.Interfaces.Workflow;
namespace Yavsc.Models.Haircut
diff --git a/src/Yavsc.Server/Models/HairCut/HairMultiCutQuery.cs b/src/Yavsc.Server/Models/HairCut/HairMultiCutQuery.cs
index beb7da9ac..21ae437ce 100644
--- a/src/Yavsc.Server/Models/HairCut/HairMultiCutQuery.cs
+++ b/src/Yavsc.Server/Models/HairCut/HairMultiCutQuery.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Yavsc.Models.Billing;
diff --git a/src/Yavsc.Server/Models/HairCut/HairPrestation.cs b/src/Yavsc.Server/Models/HairCut/HairPrestation.cs
index 2e2cf8ca6..6153f6483 100644
--- a/src/Yavsc.Server/Models/HairCut/HairPrestation.cs
+++ b/src/Yavsc.Server/Models/HairCut/HairPrestation.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Reflection;
diff --git a/src/Yavsc.Server/Models/HairCut/Views/HaircutQueryInfo.cs b/src/Yavsc.Server/Models/HairCut/Views/HaircutQueryInfo.cs
index 4099dbcaa..c9213862e 100644
--- a/src/Yavsc.Server/Models/HairCut/Views/HaircutQueryInfo.cs
+++ b/src/Yavsc.Server/Models/HairCut/Views/HaircutQueryInfo.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
//
// HaircutQueryInfo.cs
diff --git a/src/Yavsc.Server/Models/IT/SourceCode/GitClone.cs b/src/Yavsc.Server/Models/IT/SourceCode/GitClone.cs
index d58551a65..826e5de38 100644
--- a/src/Yavsc.Server/Models/IT/SourceCode/GitClone.cs
+++ b/src/Yavsc.Server/Models/IT/SourceCode/GitClone.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
// // GitClone.cs
// /*
// paul 21/06/2018 11:27 20182018 6 21
diff --git a/src/Yavsc.Server/Models/IT/SourceCode/ProjectBuild.cs b/src/Yavsc.Server/Models/IT/SourceCode/ProjectBuild.cs
index eb1afe214..f65b17b51 100644
--- a/src/Yavsc.Server/Models/IT/SourceCode/ProjectBuild.cs
+++ b/src/Yavsc.Server/Models/IT/SourceCode/ProjectBuild.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using System.Diagnostics;
namespace Yavsc.Server.Models.IT.SourceCode
diff --git a/src/Yavsc.Server/Models/IT/SourceCode/SingleCmdProjectBatch.cs b/src/Yavsc.Server/Models/IT/SourceCode/SingleCmdProjectBatch.cs
index 0fb2116f5..2ce162564 100644
--- a/src/Yavsc.Server/Models/IT/SourceCode/SingleCmdProjectBatch.cs
+++ b/src/Yavsc.Server/Models/IT/SourceCode/SingleCmdProjectBatch.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using System.Diagnostics;
namespace Yavsc.Server.Models.IT.SourceCode
diff --git a/src/Yavsc.Server/Models/IdentityUserLogin.cs b/src/Yavsc.Server/Models/IdentityUserLogin.cs
index 78567f68f..bfbd4e899 100644
--- a/src/Yavsc.Server/Models/IdentityUserLogin.cs
+++ b/src/Yavsc.Server/Models/IdentityUserLogin.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
namespace Yavsc.Models.Auth
{
using System.ComponentModel.DataAnnotations.Schema;
diff --git a/src/Yavsc.Server/Models/Kyc/TrustDeclaration.cs b/src/Yavsc.Server/Models/Kyc/TrustDeclaration.cs
index fe9fc2ec4..0a97eb6a9 100644
--- a/src/Yavsc.Server/Models/Kyc/TrustDeclaration.cs
+++ b/src/Yavsc.Server/Models/Kyc/TrustDeclaration.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
// Yavsc.Models.Kyc/TrustDeclaration.cs
namespace Yavsc.Models.Kyc
{
diff --git a/src/Yavsc.Server/Models/Kyc/TrustToken.cs b/src/Yavsc.Server/Models/Kyc/TrustToken.cs
index 8c09d39cd..2e240bae1 100644
--- a/src/Yavsc.Server/Models/Kyc/TrustToken.cs
+++ b/src/Yavsc.Server/Models/Kyc/TrustToken.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
// Yavsc.Models.Kyc/TrustToken.cs
namespace Yavsc.Models.Kyc
{
diff --git a/src/Yavsc.Server/Models/Market/Product.cs b/src/Yavsc.Server/Models/Market/Product.cs
index 84f5709ca..ae8f29199 100644
--- a/src/Yavsc.Server/Models/Market/Product.cs
+++ b/src/Yavsc.Server/Models/Market/Product.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using System.ComponentModel.DataAnnotations;
diff --git a/src/Yavsc.Server/Models/Relationship/StaticContact.cs b/src/Yavsc.Server/Models/Relationship/StaticContact.cs
index 05ebf04da..7ae6ab6ae 100644
--- a/src/Yavsc.Server/Models/Relationship/StaticContact.cs
+++ b/src/Yavsc.Server/Models/Relationship/StaticContact.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
namespace Yavsc.Models.Relationship
{
diff --git a/src/Yavsc.Server/Models/Workflow/Activity.cs b/src/Yavsc.Server/Models/Workflow/Activity.cs
index e82ac9709..0f813a273 100644
--- a/src/Yavsc.Server/Models/Workflow/Activity.cs
+++ b/src/Yavsc.Server/Models/Workflow/Activity.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Newtonsoft.Json;
@@ -37,7 +35,7 @@ namespace Yavsc.Models.Workflow
public virtual List Children { get; set; }
[Display(Name = "Description")]
- public string? Description { get; set; }
+ public string Description { get; set; }
[Display(Name = "Photo")]
public string? Photo { get; set; }
diff --git a/src/Yavsc.Server/Models/Workflow/PerformerProfile.cs b/src/Yavsc.Server/Models/Workflow/PerformerProfile.cs
index c2f312b84..23bd688b4 100644
--- a/src/Yavsc.Server/Models/Workflow/PerformerProfile.cs
+++ b/src/Yavsc.Server/Models/Workflow/PerformerProfile.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
diff --git a/src/Yavsc.Server/Models/Workflow/RdvQuery.cs b/src/Yavsc.Server/Models/Workflow/RdvQuery.cs
index cd56f3676..f821fc75d 100644
--- a/src/Yavsc.Server/Models/Workflow/RdvQuery.cs
+++ b/src/Yavsc.Server/Models/Workflow/RdvQuery.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
diff --git a/src/Yavsc.Server/Models/societe.com/CompanyInfo.cs b/src/Yavsc.Server/Models/societe.com/CompanyInfo.cs
index 354bc4861..114c4d8e3 100644
--- a/src/Yavsc.Server/Models/societe.com/CompanyInfo.cs
+++ b/src/Yavsc.Server/Models/societe.com/CompanyInfo.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using System.ComponentModel.DataAnnotations;
diff --git a/src/Yavsc.Server/Services/BillingService.cs b/src/Yavsc.Server/Services/BillingService.cs
index 1a0bc199d..ad9361767 100644
--- a/src/Yavsc.Server/Services/BillingService.cs
+++ b/src/Yavsc.Server/Services/BillingService.cs
@@ -1,7 +1,6 @@
using System.Reflection;
using Microsoft.EntityFrameworkCore;
using Yavsc.Abstract.Workflow;
-using Yavsc.Helpers;
using Yavsc.Models;
namespace Yavsc.Services
@@ -36,34 +35,7 @@ namespace Yavsc.Services
public static IQuery GetBillable(ApplicationDbContext context, string billingCode, long queryId)
{
- if (context is null) throw new ArgumentNullException(nameof(context));
- if (string.IsNullOrWhiteSpace(billingCode) || queryId <= 0)
- {
- return null;
- }
-
- if (Billing.Count == 0)
- {
- WorkflowHelpers.ConfigureBillingService();
- }
-
- var getter = Billing
- .FirstOrDefault(kvp => string.Equals(kvp.Key, billingCode.Trim(), StringComparison.OrdinalIgnoreCase))
- .Value;
-
- if (getter is null)
- {
- return null;
- }
-
- try
- {
- return getter(context, queryId);
- }
- catch (InvalidOperationException)
- {
- return null;
- }
+ throw new NotImplementedException();
}
diff --git a/src/Yavsc.Server/Services/BlogSpotService.cs b/src/Yavsc.Server/Services/BlogSpotService.cs
index 20f7245e5..a08326303 100644
--- a/src/Yavsc.Server/Services/BlogSpotService.cs
+++ b/src/Yavsc.Server/Services/BlogSpotService.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using System.Diagnostics;
using System.Security.Claims;
using Microsoft.AspNetCore.Authorization;
diff --git a/src/Yavsc.Server/Services/ClaudeModerationService.cs b/src/Yavsc.Server/Services/ClaudeModerationService.cs
index a47952318..a510e55cb 100644
--- a/src/Yavsc.Server/Services/ClaudeModerationService.cs
+++ b/src/Yavsc.Server/Services/ClaudeModerationService.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using Yavsc.Moderation;
using Yavsc.Abstract.Interfaces;
using Anthropic.SDK;
diff --git a/src/Yavsc.Server/Services/LiveProcessor.cs b/src/Yavsc.Server/Services/LiveProcessor.cs
index 560ee6d0a..f10a8201a 100644
--- a/src/Yavsc.Server/Services/LiveProcessor.cs
+++ b/src/Yavsc.Server/Services/LiveProcessor.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using System.Collections.Concurrent;
using System.Net.WebSockets;
using Yavsc.Models;
diff --git a/src/Yavsc.Server/Services/MailSender.cs b/src/Yavsc.Server/Services/MailSender.cs
index 81518eddb..592a43ba6 100644
--- a/src/Yavsc.Server/Services/MailSender.cs
+++ b/src/Yavsc.Server/Services/MailSender.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using MailKit.Net.Smtp;
using MailKit.Security;
using Microsoft.Extensions.Logging;
diff --git a/src/Yavsc.Server/Services/PermissionHandler.cs b/src/Yavsc.Server/Services/PermissionHandler.cs
index 77ee9fd57..6848070ac 100644
--- a/src/Yavsc.Server/Services/PermissionHandler.cs
+++ b/src/Yavsc.Server/Services/PermissionHandler.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using System.Security.Claims;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
diff --git a/src/Yavsc.Server/Services/ProfileService.cs b/src/Yavsc.Server/Services/ProfileService.cs
index 3b7b5121a..b6da3a568 100644
--- a/src/Yavsc.Server/Services/ProfileService.cs
+++ b/src/Yavsc.Server/Services/ProfileService.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using System.Security.Claims;
using IdentityModel;
using IdentityServer8.Models;
diff --git a/src/Yavsc.Server/Settings/SiteSettings.cs b/src/Yavsc.Server/Settings/SiteSettings.cs
index 3d604f79f..ef74781de 100644
--- a/src/Yavsc.Server/Settings/SiteSettings.cs
+++ b/src/Yavsc.Server/Settings/SiteSettings.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using Yavsc.Models.Relationship;
namespace Yavsc
diff --git a/src/Yavsc.Server/ViewModels/Account/ForgotPasswordViewModel.cs b/src/Yavsc.Server/ViewModels/Account/ForgotPasswordViewModel.cs
index 903d4c8b3..6af77fe4d 100644
--- a/src/Yavsc.Server/ViewModels/Account/ForgotPasswordViewModel.cs
+++ b/src/Yavsc.Server/ViewModels/Account/ForgotPasswordViewModel.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using System.ComponentModel.DataAnnotations;
diff --git a/src/Yavsc.Server/ViewModels/Account/SignInModel.cs b/src/Yavsc.Server/ViewModels/Account/SignInModel.cs
old mode 100644
new mode 100755
index 6375c40fe..d2aa69ad2
--- a/src/Yavsc.Server/ViewModels/Account/SignInModel.cs
+++ b/src/Yavsc.Server/ViewModels/Account/SignInModel.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using System.ComponentModel.DataAnnotations;
namespace Yavsc.ViewModels.Account
diff --git a/src/Yavsc.Server/ViewModels/Account/UnregisterViewModel.cs b/src/Yavsc.Server/ViewModels/Account/UnregisterViewModel.cs
index e08330440..e28fcfed8 100644
--- a/src/Yavsc.Server/ViewModels/Account/UnregisterViewModel.cs
+++ b/src/Yavsc.Server/ViewModels/Account/UnregisterViewModel.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using System.ComponentModel.DataAnnotations;
namespace Yavsc.ViewModels.Account
diff --git a/src/Yavsc.Server/ViewModels/Account/VerifyCodeViewModel.cs b/src/Yavsc.Server/ViewModels/Account/VerifyCodeViewModel.cs
index 5252ff4f6..a768e249f 100644
--- a/src/Yavsc.Server/ViewModels/Account/VerifyCodeViewModel.cs
+++ b/src/Yavsc.Server/ViewModels/Account/VerifyCodeViewModel.cs
@@ -1,5 +1,3 @@
-#nullable enable annotations
-
using System.ComponentModel.DataAnnotations;
namespace Yavsc.ViewModels.Account