1.0.7
Bessere Trennung manueller / automatischer Login Umstellung auf Sekunden wegen aktualisierter Hauptanwendung Umstellung auf Toasts bei Informationsmeldungen Abstände und Sichtbarkeiten vereinheitlicht Upgrade auf .NET9
This commit is contained in:
@@ -10,7 +10,7 @@
|
|||||||
<ShellContent
|
<ShellContent
|
||||||
Title="Stunden"
|
Title="Stunden"
|
||||||
ContentTemplate="{DataTemplate views:StundenPage}"
|
ContentTemplate="{DataTemplate views:StundenPage}"
|
||||||
Icon="{OnPlatform 'icon_watch.png', iOS='icon_watch_ios.png', MacCatalyst='icon_watch_ios.png'}" />
|
Icon="{OnPlatform 'icon_watch.png', iOS='icon_watch_ios.png', MacCatalyst='icon_watch_ios.png'}" Route="StundenPage" />
|
||||||
|
|
||||||
<ShellContent
|
<ShellContent
|
||||||
Title="Notizen"
|
Title="Notizen"
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ public partial class AppShell : Shell {
|
|||||||
Routing.RegisterRoute(nameof(Views.NotePage), typeof(Views.NotePage));
|
Routing.RegisterRoute(nameof(Views.NotePage), typeof(Views.NotePage));
|
||||||
Routing.RegisterRoute(nameof(Views.StundePage), typeof(Views.StundePage));
|
Routing.RegisterRoute(nameof(Views.StundePage), typeof(Views.StundePage));
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
29
Jugenddienst Stunden/Converter/SecondsTimeConverter.cs
Normal file
29
Jugenddienst Stunden/Converter/SecondsTimeConverter.cs
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
using System.Globalization;
|
||||||
|
|
||||||
|
namespace Jugenddienst_Stunden.Converter;
|
||||||
|
internal class SecondsTimeConverter : IValueConverter {
|
||||||
|
private int seconds;
|
||||||
|
|
||||||
|
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) {
|
||||||
|
if (value is null)
|
||||||
|
return "0:0";
|
||||||
|
if (value is int) {
|
||||||
|
seconds = (int)value;
|
||||||
|
} else {
|
||||||
|
int.TryParse((string?)value, out seconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeSpan time = TimeSpan.FromSeconds(seconds);
|
||||||
|
|
||||||
|
return (int)time.TotalHours + ":" + Math.Abs(time.Minutes);
|
||||||
|
|
||||||
|
//return time.ToString(@"hh\:mm");
|
||||||
|
//return time.ToString(@"hh\:mm\:ss");
|
||||||
|
|
||||||
|
//return "00:00";
|
||||||
|
}
|
||||||
|
|
||||||
|
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -244,14 +244,16 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="CommunityToolkit.Maui" Version="11.1.0" />
|
||||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
|
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
|
||||||
<PackageReference Include="Microsoft.Maui.Controls" Version="9.0.30">
|
<PackageReference Include="Microsoft.Maui.Controls" Version="9.0.40">
|
||||||
<TreatAsUsed>true</TreatAsUsed>
|
<TreatAsUsed>true</TreatAsUsed>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.Maui.Controls.Compatibility" Version="9.0.30" />
|
<PackageReference Include="Microsoft.Maui.Controls.Compatibility" Version="9.0.40" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="9.0.1" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="9.0.2" />
|
||||||
<PackageReference Include="Microsoft.Maui.Graphics" Version="9.0.30" />
|
<PackageReference Include="Microsoft.Maui.Graphics" Version="9.0.40" />
|
||||||
<PackageReference Include="Microsoft.NET.Runtime.MonoAOTCompiler.Task" Version="9.0.1" />
|
<PackageReference Include="Microsoft.NET.Runtime.MonoAOTCompiler.Task" Version="9.0.2" />
|
||||||
|
<PackageReference Include="Microsoft.NET.Runtime.WebAssembly.Wasi.Sdk" Version="9.0.2" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
<PackageReference Include="ZXing.Net.Maui.Controls" Version="0.4.0" />
|
<PackageReference Include="ZXing.Net.Maui.Controls" Version="0.4.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Jugenddienst_Stunden.Models;
|
using CommunityToolkit.Maui;
|
||||||
|
using Jugenddienst_Stunden.Models;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using ZXing.Net.Maui.Controls;
|
using ZXing.Net.Maui.Controls;
|
||||||
|
|
||||||
@@ -13,6 +14,8 @@ public static class MauiProgram {
|
|||||||
var builder = MauiApp.CreateBuilder();
|
var builder = MauiApp.CreateBuilder();
|
||||||
builder
|
builder
|
||||||
.UseMauiApp<App>()
|
.UseMauiApp<App>()
|
||||||
|
// Initialize the .NET MAUI Community Toolkit by adding the below line of code
|
||||||
|
.UseMauiCommunityToolkit()
|
||||||
.ConfigureFonts(fonts => {
|
.ConfigureFonts(fonts => {
|
||||||
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
|
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
|
||||||
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
|
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
|
||||||
@@ -22,19 +25,11 @@ public static class MauiProgram {
|
|||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
if (GlobalVar.ApiKey == null) {
|
if (GlobalVar.ApiKey == null) {
|
||||||
//Preferences.Default.Set("apiKey
|
|
||||||
//Preferences.Default.Set("apiKey", "M3xneWlWNG85TmNIcmo1NnpxWkxVYS9JMDBFRlV8aHR0cDovL2hvdXJzLmRhdW5pLm1pbmUubnU6ODEvYXBwYXBp");
|
|
||||||
//Preferences.Default.Set("name", "Testserver: Lea");
|
|
||||||
//Preferences.Default.Set("surname", "Mair");
|
|
||||||
//Preferences.Default.Set("EmployeeId", 3);
|
|
||||||
//Preferences.Default.Set("apiUrl", "http://hours.dauni.mine.nu:81/appapi");
|
|
||||||
//HoursBase HoursBase = new HoursBase();
|
|
||||||
//HoursBase.tokendata = new TokenData("MTQxfHNkdFptQkNZTXlPT3ZyMHNBZDl0UnVxNExMRXxodHRwOi8vaG91cnMuZGF1bmkubWluZS5udTo4MS9hcHBhcGk=");
|
|
||||||
GlobalVar.ApiKey = Preferences.Default.Get("apiKey", "MTQxfHNkdFptQkNZTXlPT3ZyMHNBZDl0UnVxNExMRXxodHRwOi8vaG91cnMuZGF1bmkubWluZS5udTo4MS9hcHBhcGk=");
|
GlobalVar.ApiKey = Preferences.Default.Get("apiKey", "MTQxfHNkdFptQkNZTXlPT3ZyMHNBZDl0UnVxNExMRXxodHRwOi8vaG91cnMuZGF1bmkubWluZS5udTo4MS9hcHBhcGk=");
|
||||||
GlobalVar.Name = Preferences.Default.Get("name", "Testserver: Isabell");
|
GlobalVar.Name = Preferences.Default.Get("name", "Testserver: Isabell");
|
||||||
GlobalVar.Surname = Preferences.Default.Get("surname", "Biasi");
|
GlobalVar.Surname = Preferences.Default.Get("surname", "Biasi");
|
||||||
GlobalVar.EmployeeId = Preferences.Default.Get("EmployeeId", 141);
|
GlobalVar.EmployeeId = Preferences.Default.Get("EmployeeId", 141);
|
||||||
GlobalVar.ApiUrl = Preferences.Default.Get("apiUrl", "http://hours.dauni.mine.nu:81/appapi");
|
GlobalVar.ApiUrl = Preferences.Default.Get("apiUrl", "https://hours.dauni.mine.nu/appapi");
|
||||||
}
|
}
|
||||||
builder.Logging.AddDebug();
|
builder.Logging.AddDebug();
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -29,9 +29,9 @@ internal static class BaseFunc {
|
|||||||
using (HttpResponseMessage HttpResponseMessage = await client.GetAsync(url).ConfigureAwait(false)) {
|
using (HttpResponseMessage HttpResponseMessage = await client.GetAsync(url).ConfigureAwait(false)) {
|
||||||
var byteArray = await HttpResponseMessage.Content.ReadAsByteArrayAsync();
|
var byteArray = await HttpResponseMessage.Content.ReadAsByteArrayAsync();
|
||||||
string responseData = Encoding.UTF8.GetString(byteArray);
|
string responseData = Encoding.UTF8.GetString(byteArray);
|
||||||
using (HttpContent HttpContent = HttpResponseMessage.Content) {
|
//using (HttpContent HttpContent = HttpResponseMessage.Content) {
|
||||||
//responseData = await HttpContent.ReadAsStringAsync();
|
// //responseData = await HttpContent.ReadAsStringAsync();
|
||||||
}
|
//}
|
||||||
if (HttpResponseMessage.StatusCode == System.Net.HttpStatusCode.OK) {
|
if (HttpResponseMessage.StatusCode == System.Net.HttpStatusCode.OK) {
|
||||||
return responseData;
|
return responseData;
|
||||||
} else {
|
} else {
|
||||||
@@ -98,6 +98,9 @@ internal static class BaseFunc {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Notiz laden
|
||||||
|
/// </summary>
|
||||||
internal static Note Load(string filename) {
|
internal static Note Load(string filename) {
|
||||||
filename = System.IO.Path.Combine(FileSystem.AppDataDirectory, filename);
|
filename = System.IO.Path.Combine(FileSystem.AppDataDirectory, filename);
|
||||||
|
|
||||||
@@ -169,6 +172,9 @@ internal static class BaseFunc {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stundeneintrag löschen
|
||||||
|
/// </summary>
|
||||||
internal static async Task DeleteItemAsync(string url, string token) {
|
internal static async Task DeleteItemAsync(string url, string token) {
|
||||||
using (HttpClient client = new HttpClient() { Timeout = TimeSpan.FromSeconds(15) }) {
|
using (HttpClient client = new HttpClient() { Timeout = TimeSpan.FromSeconds(15) }) {
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ namespace Jugenddienst_Stunden.Models;
|
|||||||
internal static class HoursBase {
|
internal static class HoursBase {
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// what can be: "settings", "hours", date="YYYY-MM-DD", id=<int/>
|
/// Laden ... what can be: "settings", "hours", date="YYYY-MM-DD", id=<int/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Entire response</returns>
|
/// <returns>Entire response</returns>
|
||||||
internal static async Task<BaseResponse> LoadBase(string what) {
|
internal static async Task<BaseResponse> LoadBase(string what) {
|
||||||
@@ -16,7 +16,7 @@ internal static class HoursBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Einstellungen
|
/// Einstellungen laden
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Settings only</returns>
|
/// <returns>Settings only</returns>
|
||||||
internal static async Task<Settings> LoadSettings() {
|
internal static async Task<Settings> LoadSettings() {
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ using System.Collections.ObjectModel;
|
|||||||
namespace Jugenddienst_Stunden.Types;
|
namespace Jugenddienst_Stunden.Types;
|
||||||
|
|
||||||
internal class Hours : ObservableObject {
|
internal class Hours : ObservableObject {
|
||||||
public string? Zeit;
|
public int? Zeit;
|
||||||
public string? Nominal;
|
public int? Nominal;
|
||||||
//public Dictionary<DateOnly,NominalDay> nominal_day_api;
|
//public Dictionary<DateOnly,NominalDay> nominal_day_api;
|
||||||
public List<NominalDay>? Nominal_day_api;
|
public List<NominalDay>? Nominal_day_api;
|
||||||
//public Dictionary<int,NominalWeek> nominal_week_api;
|
//public Dictionary<int,NominalWeek> nominal_week_api;
|
||||||
@@ -21,16 +21,16 @@ internal class Hours : ObservableObject {
|
|||||||
public List<TimeDay> zeit_total_daily_api;
|
public List<TimeDay> zeit_total_daily_api;
|
||||||
public List<DayTime>? daytime;
|
public List<DayTime>? daytime;
|
||||||
//public List<string> wochensumme;
|
//public List<string> wochensumme;
|
||||||
public string overtime_month;
|
public int overtime_month;
|
||||||
public string overtime;
|
public int overtime;
|
||||||
//public List<string> overtime_day;
|
//public List<string> overtime_day;
|
||||||
public string zeitausgleich;
|
public int zeitausgleich;
|
||||||
public string zeitausgleich_month;
|
public int zeitausgleich_month;
|
||||||
public string holiday;
|
public int holiday;
|
||||||
public string krankheit;
|
public int krankheit;
|
||||||
public string weiterbildung;
|
public int weiterbildung;
|
||||||
public string bereitschaft;
|
public int bereitschaft;
|
||||||
public string bereitschaft_month;
|
public int bereitschaft_month;
|
||||||
//public Operator operator_api;
|
//public Operator operator_api;
|
||||||
public DateTime Today;
|
public DateTime Today;
|
||||||
public DateTime Date;
|
public DateTime Date;
|
||||||
|
|||||||
@@ -2,6 +2,6 @@
|
|||||||
internal class NominalDay {
|
internal class NominalDay {
|
||||||
public int day_number;
|
public int day_number;
|
||||||
public int month_number;
|
public int month_number;
|
||||||
public decimal hours;
|
public int hours;
|
||||||
public DateOnly date;
|
public DateOnly date;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,5 +2,5 @@
|
|||||||
|
|
||||||
internal class NominalWeek {
|
internal class NominalWeek {
|
||||||
public int Week_number;
|
public int Week_number;
|
||||||
public decimal Hours;
|
public int Hours;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ public partial class StundeViewModel : ObservableObject, IQueryAttributable {
|
|||||||
public event EventHandler<string> AlertEvent;
|
public event EventHandler<string> AlertEvent;
|
||||||
public event EventHandler<string> InfoEvent;
|
public event EventHandler<string> InfoEvent;
|
||||||
public event Func<string, string, Task<bool>> ConfirmEvent;
|
public event Func<string, string, Task<bool>> ConfirmEvent;
|
||||||
|
//public event Func<string, string, string?, string?, Task<bool>> ConfirmEvent;
|
||||||
|
//public event EventHandler<ConfirmEventArgs> ConfirmEvent;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gemeinden für die Auswahlliste
|
/// Gemeinden für die Auswahlliste
|
||||||
@@ -73,6 +75,7 @@ public partial class StundeViewModel : ObservableObject, IQueryAttributable {
|
|||||||
public ICommand DeleteConfirmCommand { get; private set; }
|
public ICommand DeleteConfirmCommand { get; private set; }
|
||||||
//public ICommand LoadDataCommand { get; private set; }
|
//public ICommand LoadDataCommand { get; private set; }
|
||||||
|
|
||||||
|
|
||||||
public StundeViewModel() {
|
public StundeViewModel() {
|
||||||
SaveCommand = new AsyncRelayCommand(Save);
|
SaveCommand = new AsyncRelayCommand(Save);
|
||||||
//DeleteCommand = new AsyncRelayCommand(Delete);
|
//DeleteCommand = new AsyncRelayCommand(Delete);
|
||||||
@@ -95,7 +98,7 @@ public partial class StundeViewModel : ObservableObject, IQueryAttributable {
|
|||||||
|
|
||||||
GemeindeAktivSet = Settings.GemeindeAktivSet;
|
GemeindeAktivSet = Settings.GemeindeAktivSet;
|
||||||
ProjektAktivSet = Settings.ProjektAktivSet;
|
ProjektAktivSet = Settings.ProjektAktivSet;
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
AlertEvent?.Invoke(this, e.Message);
|
AlertEvent?.Invoke(this, e.Message);
|
||||||
}
|
}
|
||||||
@@ -103,26 +106,40 @@ public partial class StundeViewModel : ObservableObject, IQueryAttributable {
|
|||||||
|
|
||||||
async Task Save() {
|
async Task Save() {
|
||||||
bool exceptionOccurred = false;
|
bool exceptionOccurred = false;
|
||||||
try {
|
bool proceed = true;
|
||||||
await HoursBase.SaveEntry(DayTime);
|
if (DayTime.TimeSpanVon == DayTime.TimeSpanBis && DayTime.FreistellungAktiv.Name == null) {
|
||||||
} catch (Exception e) {
|
proceed = false;
|
||||||
AlertEvent?.Invoke(this, e.Message);
|
AlertEvent?.Invoke(this, "Uhrzeiten sollten unterschiedlich sein");
|
||||||
exceptionOccurred = true;
|
|
||||||
}
|
}
|
||||||
if (!exceptionOccurred) {
|
|
||||||
if (DayTime.Id != null) {
|
if (proceed) {
|
||||||
await Shell.Current.GoToAsync($"..?saved={DayTime.Id}");
|
try {
|
||||||
} else {
|
await HoursBase.SaveEntry(DayTime);
|
||||||
await Shell.Current.GoToAsync($"..?date={DayTime.Day.ToString("yyyy-MM-dd")}");
|
} catch (Exception e) {
|
||||||
|
AlertEvent?.Invoke(this, e.Message);
|
||||||
|
exceptionOccurred = true;
|
||||||
|
}
|
||||||
|
if (!exceptionOccurred) {
|
||||||
|
if (DayTime.Id != null) {
|
||||||
|
await Shell.Current.GoToAsync($"..?saved={DayTime.Id}");
|
||||||
|
} else {
|
||||||
|
await Shell.Current.GoToAsync($"..?date={DayTime.Day.ToString("yyyy-MM-dd")}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Löschen ohne Bestätigung
|
||||||
|
/// </summary>
|
||||||
private async Task Delete() {
|
private async Task Delete() {
|
||||||
await HoursBase.DeleteEntry(DayTime);
|
await HoursBase.DeleteEntry(DayTime);
|
||||||
await Shell.Current.GoToAsync($"..?date={DayTime.Day.ToString("yyyy-MM-dd")}");
|
await Shell.Current.GoToAsync($"..?date={DayTime.Day.ToString("yyyy-MM-dd")}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Löschen mit Bestätigung
|
||||||
|
/// </summary>
|
||||||
private async Task DeleteConfirm() {
|
private async Task DeleteConfirm() {
|
||||||
if (ConfirmEvent != null) {
|
if (ConfirmEvent != null) {
|
||||||
bool answer = await ConfirmEvent.Invoke("Achtung", "Löschen kann nicht ungeschehen gemacht werden. Fortfahren?");
|
bool answer = await ConfirmEvent.Invoke("Achtung", "Löschen kann nicht ungeschehen gemacht werden. Fortfahren?");
|
||||||
@@ -140,7 +157,8 @@ public partial class StundeViewModel : ObservableObject, IQueryAttributable {
|
|||||||
/// Anwenden der Query-Parameter
|
/// Anwenden der Query-Parameter
|
||||||
/// </summary>
|
/// </summary>
|
||||||
async void IQueryAttributable.ApplyQueryAttributes(IDictionary<string, object> query) {
|
async void IQueryAttributable.ApplyQueryAttributes(IDictionary<string, object> query) {
|
||||||
|
//load beinhaltet die ID: Eintrag bearbeiten
|
||||||
|
//date beinhaltet einen Tag: Neuen Eintrag erstellen
|
||||||
if (query.ContainsKey("load")) {
|
if (query.ContainsKey("load")) {
|
||||||
|
|
||||||
//DateTime heute = DateTime.Now;
|
//DateTime heute = DateTime.Now;
|
||||||
@@ -154,7 +172,7 @@ public partial class StundeViewModel : ObservableObject, IQueryAttributable {
|
|||||||
DayTime = dat.daytime;
|
DayTime = dat.daytime;
|
||||||
DayTime.TimeSpanVon = dat.daytime.Begin.ToTimeSpan();
|
DayTime.TimeSpanVon = dat.daytime.Begin.ToTimeSpan();
|
||||||
DayTime.TimeSpanBis = dat.daytime.End.ToTimeSpan();
|
DayTime.TimeSpanBis = dat.daytime.End.ToTimeSpan();
|
||||||
|
|
||||||
OptionsGemeinde = dat.settings.Gemeinden ?? new List<Gemeinde>();
|
OptionsGemeinde = dat.settings.Gemeinden ?? new List<Gemeinde>();
|
||||||
OptionsProjekt = dat.settings.Projekte ?? new List<Projekt>();
|
OptionsProjekt = dat.settings.Projekte ?? new List<Projekt>();
|
||||||
OptionsFreistellung = dat.settings.Freistellungen ?? new List<Freistellung>();
|
OptionsFreistellung = dat.settings.Freistellungen ?? new List<Freistellung>();
|
||||||
@@ -162,7 +180,12 @@ public partial class StundeViewModel : ObservableObject, IQueryAttributable {
|
|||||||
DayTime.GemeindeAktiv = OptionsGemeinde.FirstOrDefault(Gemeinde => Gemeinde.Id == DayTime.Gemeinde) ?? new Gemeinde();
|
DayTime.GemeindeAktiv = OptionsGemeinde.FirstOrDefault(Gemeinde => Gemeinde.Id == DayTime.Gemeinde) ?? new Gemeinde();
|
||||||
DayTime.ProjektAktiv = OptionsProjekt.FirstOrDefault(Projekt => Projekt.Id == DayTime.Projekt) ?? new Projekt();
|
DayTime.ProjektAktiv = OptionsProjekt.FirstOrDefault(Projekt => Projekt.Id == DayTime.Projekt) ?? new Projekt();
|
||||||
DayTime.FreistellungAktiv = OptionsFreistellung.FirstOrDefault(Freistellung => Freistellung.Id == DayTime.Free) ?? new Freistellung();
|
DayTime.FreistellungAktiv = OptionsFreistellung.FirstOrDefault(Freistellung => Freistellung.Id == DayTime.Free) ?? new Freistellung();
|
||||||
//OnPropertyChanged(nameof(DayTime));
|
|
||||||
|
//Evtl. noch die anderen Zeiten des gleichen Tages holen
|
||||||
|
BaseResponse dat1 = await HoursBase.LoadBase("date=" + DayTime.Day.ToString("yyyy-MM-dd"));
|
||||||
|
DayTimes = dat1.daytimes;
|
||||||
|
OnPropertyChanged(nameof(DayTime));
|
||||||
|
OnPropertyChanged(nameof(DayTimes));
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
AlertEvent?.Invoke(this, e.Message);
|
AlertEvent?.Invoke(this, e.Message);
|
||||||
@@ -171,7 +194,7 @@ public partial class StundeViewModel : ObservableObject, IQueryAttributable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (System.String.IsNullOrEmpty(DayTime.Description)) {
|
if (System.String.IsNullOrEmpty(DayTime.Description)) {
|
||||||
AlertEvent?.Invoke(this, "Eintrag hat keinen Beschreibungstext");
|
InfoEvent?.Invoke(this, "Eintrag hat keinen Beschreibungstext");
|
||||||
}
|
}
|
||||||
SubTitle = DayTime.Day.ToString("dddd, d. MMMM yyyy");
|
SubTitle = DayTime.Day.ToString("dddd, d. MMMM yyyy");
|
||||||
OnPropertyChanged(nameof(SubTitle));
|
OnPropertyChanged(nameof(SubTitle));
|
||||||
@@ -197,7 +220,7 @@ public partial class StundeViewModel : ObservableObject, IQueryAttributable {
|
|||||||
|
|
||||||
GemeindeAktivSet = dat.settings.GemeindeAktivSet;
|
GemeindeAktivSet = dat.settings.GemeindeAktivSet;
|
||||||
ProjektAktivSet = dat.settings.ProjektAktivSet;
|
ProjektAktivSet = dat.settings.ProjektAktivSet;
|
||||||
|
|
||||||
} catch (Exception) {
|
} catch (Exception) {
|
||||||
//Ein Tag ohne Einträge gibt eine Fehlermeldung,
|
//Ein Tag ohne Einträge gibt eine Fehlermeldung,
|
||||||
//die soll aber ignoriert werden, weil beim Neueintrag ist das ja Wurscht
|
//die soll aber ignoriert werden, weil beim Neueintrag ist das ja Wurscht
|
||||||
@@ -213,7 +236,7 @@ public partial class StundeViewModel : ObservableObject, IQueryAttributable {
|
|||||||
|
|
||||||
SubTitle = _date.ToString("dddd, d. MMMM yyyy");
|
SubTitle = _date.ToString("dddd, d. MMMM yyyy");
|
||||||
FreistellungEnabled = true;
|
FreistellungEnabled = true;
|
||||||
|
|
||||||
OnPropertyChanged(nameof(SubTitle));
|
OnPropertyChanged(nameof(SubTitle));
|
||||||
//OnPropertyChanged(nameof(DayTime));
|
//OnPropertyChanged(nameof(DayTime));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ using Jugenddienst_Stunden.Types;
|
|||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
|
using CommunityToolkit.Maui.Alerts;
|
||||||
|
using CommunityToolkit.Maui.Core;
|
||||||
|
|
||||||
|
|
||||||
namespace Jugenddienst_Stunden.ViewModels;
|
namespace Jugenddienst_Stunden.ViewModels;
|
||||||
@@ -13,8 +15,6 @@ namespace Jugenddienst_Stunden.ViewModels;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal partial class StundenViewModel : ObservableObject, IQueryAttributable, INotifyPropertyChanged {
|
internal partial class StundenViewModel : ObservableObject, IQueryAttributable, INotifyPropertyChanged {
|
||||||
|
|
||||||
public string LoadOverview => "Lade Summen für " + DateTime.Today.ToString("MMMM");
|
|
||||||
|
|
||||||
public ICommand NewEntryCommand { get; }
|
public ICommand NewEntryCommand { get; }
|
||||||
public ICommand SelectEntryCommand { get; }
|
public ICommand SelectEntryCommand { get; }
|
||||||
public ICommand LoadDataCommand { get; private set; }
|
public ICommand LoadDataCommand { get; private set; }
|
||||||
@@ -25,6 +25,13 @@ internal partial class StundenViewModel : ObservableObject, IQueryAttributable,
|
|||||||
public event EventHandler<string> AlertEvent;
|
public event EventHandler<string> AlertEvent;
|
||||||
public event EventHandler<string> InfoEvent;
|
public event EventHandler<string> InfoEvent;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Beschriftung Button Monatsübersicht
|
||||||
|
/// </summary>
|
||||||
|
[ObservableProperty]
|
||||||
|
private string loadOverview;
|
||||||
|
|
||||||
//private HoursBase HoursBase = new HoursBase();
|
//private HoursBase HoursBase = new HoursBase();
|
||||||
internal Settings Settings = new Settings();
|
internal Settings Settings = new Settings();
|
||||||
|
|
||||||
@@ -45,7 +52,7 @@ internal partial class StundenViewModel : ObservableObject, IQueryAttributable,
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private List<DayTime> dayTimes = new List<DayTime>();
|
private List<DayTime> dayTimes = new List<DayTime>();
|
||||||
|
|
||||||
public string Title { get; set; } = GlobalVar.Name + " " + GlobalVar.Surname;
|
public string Title { get; set; } = GlobalVar.Name + " " + GlobalVar.Surname;
|
||||||
|
|
||||||
private Hours _hour;
|
private Hours _hour;
|
||||||
@@ -76,7 +83,7 @@ internal partial class StundenViewModel : ObservableObject, IQueryAttributable,
|
|||||||
set {
|
set {
|
||||||
if (dateToday != value) {
|
if (dateToday != value) {
|
||||||
dateToday = value;
|
dateToday = value;
|
||||||
//GetDay = value;
|
LoadOverview = "Lade Summen für " + dateToday.ToString("MMMM");
|
||||||
//OnPropertyChanged();
|
//OnPropertyChanged();
|
||||||
Task.Run(() => LoadDay(value));
|
Task.Run(() => LoadDay(value));
|
||||||
}
|
}
|
||||||
@@ -93,28 +100,28 @@ internal partial class StundenViewModel : ObservableObject, IQueryAttributable,
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Monatsübersicht: Sollstunden
|
/// Monatsübersicht: Sollstunden
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? Nominal {
|
public int? Nominal {
|
||||||
get => Hours.Nominal;
|
get => Hours.Nominal;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Monatsübersicht: Differenz zwischen Soll und geleisteten Stunden
|
/// Monatsübersicht: Differenz zwischen Soll und geleisteten Stunden
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? Overtime {
|
public int? Overtime {
|
||||||
get => Hours.overtime;
|
get => Hours.overtime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Monatsübersicht: Restüberstunden insgesamt
|
/// Monatsübersicht: Restüberstunden insgesamt
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string OvertimeMonth {
|
public int OvertimeMonth {
|
||||||
get => Hours.overtime_month;
|
get => Hours.overtime_month;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Monatsübersicht: Resturlaub
|
/// Monatsübersicht: Resturlaub
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Holiday {
|
public int Holiday {
|
||||||
get => Hours.holiday;
|
get => Hours.holiday;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,12 +145,15 @@ internal partial class StundenViewModel : ObservableObject, IQueryAttributable,
|
|||||||
private bool doContinue = true;
|
private bool doContinue = true;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// CTOR
|
/// CTOR
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public StundenViewModel() {
|
public StundenViewModel() {
|
||||||
_hour = new Hours();
|
_hour = new Hours();
|
||||||
|
|
||||||
|
LoadOverview = "Lade Summen für " + DateToday.ToString("MMMM");
|
||||||
|
|
||||||
LoadDataCommand = new AsyncRelayCommand(LoadData);
|
LoadDataCommand = new AsyncRelayCommand(LoadData);
|
||||||
NewEntryCommand = new AsyncRelayCommand(NewEntryAsync);
|
NewEntryCommand = new AsyncRelayCommand(NewEntryAsync);
|
||||||
SelectEntryCommand = new AsyncRelayCommand<DayTime>(SelectEntryAsync);
|
SelectEntryCommand = new AsyncRelayCommand<DayTime>(SelectEntryAsync);
|
||||||
@@ -183,7 +193,7 @@ internal partial class StundenViewModel : ObservableObject, IQueryAttributable,
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private async Task LoadData() {
|
private async Task LoadData() {
|
||||||
try {
|
try {
|
||||||
BaseResponse dat = await HoursBase.LoadBase("hours");
|
BaseResponse dat = await HoursBase.LoadBase("hours&month=" + DateToday.ToString("MM"));
|
||||||
_hour = dat.hour;
|
_hour = dat.hour;
|
||||||
//_hour = await HoursBase.LoadData();
|
//_hour = await HoursBase.LoadData();
|
||||||
RefreshProperties();
|
RefreshProperties();
|
||||||
@@ -198,6 +208,7 @@ internal partial class StundenViewModel : ObservableObject, IQueryAttributable,
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public async Task LoadDay(DateTime date) {
|
public async Task LoadDay(DateTime date) {
|
||||||
DayTotal = new TimeOnly(0);
|
DayTotal = new TimeOnly(0);
|
||||||
|
Sollstunden = new TimeOnly(0);
|
||||||
try {
|
try {
|
||||||
//_dayTimes = await HoursBase.LoadDay(date);
|
//_dayTimes = await HoursBase.LoadDay(date);
|
||||||
BaseResponse dat = await HoursBase.LoadBase("date=" + date.ToString("yyyy-MM-dd"));
|
BaseResponse dat = await HoursBase.LoadBase("date=" + date.ToString("yyyy-MM-dd"));
|
||||||
@@ -206,6 +217,7 @@ internal partial class StundenViewModel : ObservableObject, IQueryAttributable,
|
|||||||
Settings = dat.settings;
|
Settings = dat.settings;
|
||||||
GemeindeAktivSet = Settings.GemeindeAktivSet;
|
GemeindeAktivSet = Settings.GemeindeAktivSet;
|
||||||
ProjektAktivSet = Settings.ProjektAktivSet;
|
ProjektAktivSet = Settings.ProjektAktivSet;
|
||||||
|
|
||||||
|
|
||||||
OnPropertyChanged(nameof(GemeindeAktivSet));
|
OnPropertyChanged(nameof(GemeindeAktivSet));
|
||||||
OnPropertyChanged(nameof(ProjektAktivSet));
|
OnPropertyChanged(nameof(ProjektAktivSet));
|
||||||
@@ -241,23 +253,25 @@ internal partial class StundenViewModel : ObservableObject, IQueryAttributable,
|
|||||||
} finally {
|
} finally {
|
||||||
OnPropertyChanged(nameof(DayTotal));
|
OnPropertyChanged(nameof(DayTotal));
|
||||||
OnPropertyChanged(nameof(Sollstunden));
|
OnPropertyChanged(nameof(Sollstunden));
|
||||||
|
OnPropertyChanged(nameof(DateToday));
|
||||||
|
OnPropertyChanged(nameof(LoadOverview));
|
||||||
//OnPropertyChanged(nameof(DayTimes));
|
//OnPropertyChanged(nameof(DayTimes));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async void IQueryAttributable.ApplyQueryAttributes(IDictionary<string, object> query) {
|
async void IQueryAttributable.ApplyQueryAttributes(IDictionary<string, object> query) {
|
||||||
if (query.ContainsKey("date")) {
|
if (query.ContainsKey("date")) {
|
||||||
await LoadDay(Convert.ToDateTime(query["date"]));
|
await LoadDay(Convert.ToDateTime(query["date"]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Seite aktualisieren
|
||||||
|
/// </summary>
|
||||||
private async Task RefreshItemsAsync() {
|
private async Task RefreshItemsAsync() {
|
||||||
IsRefreshing = true;
|
IsRefreshing = true;
|
||||||
|
|
||||||
// Fügen Sie hier die Logik zum Aktualisieren der Daten hinzu
|
|
||||||
//await Task.Delay(2000); // Simuliert eine Datenaktualisierung
|
//await Task.Delay(2000); // Simuliert eine Datenaktualisierung
|
||||||
await LoadDay(DateToday);
|
await LoadDay(DateToday);
|
||||||
|
|
||||||
@@ -277,6 +291,7 @@ internal partial class StundenViewModel : ObservableObject, IQueryAttributable,
|
|||||||
OnPropertyChanged(nameof(Title));
|
OnPropertyChanged(nameof(Title));
|
||||||
OnPropertyChanged(nameof(MinimumDate));
|
OnPropertyChanged(nameof(MinimumDate));
|
||||||
OnPropertyChanged(nameof(MaximumDate));
|
OnPropertyChanged(nameof(MaximumDate));
|
||||||
|
OnPropertyChanged(nameof(LoadOverview));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void OnPropertyChanged([CallerMemberName] string propertyName = null) {
|
protected void OnPropertyChanged([CallerMemberName] string propertyName = null) {
|
||||||
|
|||||||
@@ -52,13 +52,9 @@
|
|||||||
|
|
||||||
<VerticalStackLayout x:Name="LoginManual" Spacing="15">
|
<VerticalStackLayout x:Name="LoginManual" Spacing="15">
|
||||||
<Label Text="Manueller Login" FontSize="32" HorizontalOptions="Start" />
|
<Label Text="Manueller Login" FontSize="32" HorizontalOptions="Start" />
|
||||||
|
|
||||||
<Entry x:Name="UsernameEntry" Placeholder="Benutzername" Keyboard="Email" />
|
<Entry x:Name="UsernameEntry" Placeholder="Benutzername" Keyboard="Email" />
|
||||||
|
|
||||||
<Entry x:Name="PasswordEntry" Placeholder="Passwort" IsPassword="True" />
|
<Entry x:Name="PasswordEntry" Placeholder="Passwort" IsPassword="True" />
|
||||||
|
|
||||||
<Entry x:Name="ServerEntry" Placeholder="Server" Keyboard="Url" />
|
<Entry x:Name="ServerEntry" Placeholder="Server" Keyboard="Url" />
|
||||||
|
|
||||||
<Button Text="Login" Clicked="OnLoginButtonClicked" />
|
<Button Text="Login" Clicked="OnLoginButtonClicked" />
|
||||||
</VerticalStackLayout>
|
</VerticalStackLayout>
|
||||||
</VerticalStackLayout>
|
</VerticalStackLayout>
|
||||||
|
|||||||
@@ -79,8 +79,13 @@ public partial class LoginPage : ContentPage {
|
|||||||
|
|
||||||
|
|
||||||
await DisplayAlert("Login erfolgreich", user.Name + " " + user.Surname, "OK");
|
await DisplayAlert("Login erfolgreich", user.Name + " " + user.Surname, "OK");
|
||||||
if (Navigation.NavigationStack.Count > 1)
|
if (Navigation.NavigationStack.Count > 1) {
|
||||||
|
//Beim ersten Start ohne Login, wird man automatisch auf die Loginseite geleitet. Danach in der History zur<75>ck
|
||||||
await Navigation.PopAsync();
|
await Navigation.PopAsync();
|
||||||
|
} else {
|
||||||
|
//Beim manuellen Wechsel auf die Loginseite leiten wir nach erfolgreichem Login auf die Stunden<65>bersicht
|
||||||
|
await Shell.Current.GoToAsync($"//StundenPage");
|
||||||
|
}
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
await DisplayAlert("Fehler", e.Message, "OK");
|
await DisplayAlert("Fehler", e.Message, "OK");
|
||||||
@@ -126,30 +131,50 @@ public partial class LoginPage : ContentPage {
|
|||||||
var password = PasswordEntry.Text;
|
var password = PasswordEntry.Text;
|
||||||
var server = ServerEntry.Text;
|
var server = ServerEntry.Text;
|
||||||
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password) || string.IsNullOrEmpty(server)) {
|
if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password) || string.IsNullOrEmpty(server)) {
|
||||||
await DisplayAlert("Fehler", "Bitte alle Felder ausf<73>llen", "OK");
|
await DisplayAlert("Fehler", "Bitte alle Felder ausf<73>llen", "OK");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
Types.User response = await BaseFunc.AuthUserPass(username, password, server);
|
Uri uri = new Uri(InputUrlWithSchema(server));
|
||||||
|
|
||||||
|
Types.User response = await BaseFunc.AuthUserPass(username, password, uri.Scheme + "://" + uri.Authority + "/appapi");
|
||||||
|
|
||||||
GlobalVar.ApiKey = response.Token;
|
GlobalVar.ApiKey = response.Token;
|
||||||
GlobalVar.Name = response.Name;
|
GlobalVar.Name = response.Name;
|
||||||
GlobalVar.Surname = response.Surname;
|
GlobalVar.Surname = response.Surname;
|
||||||
GlobalVar.EmployeeId = response.Id;
|
GlobalVar.EmployeeId = response.Id;
|
||||||
GlobalVar.ApiUrl = server;
|
GlobalVar.ApiUrl = uri.Scheme + "://" + uri.Authority + "/appapi";
|
||||||
|
|
||||||
Title = response.Name + " " + response.Surname;
|
Title = response.Name + " " + response.Surname;
|
||||||
ServerLabel.Text = "Server: " + server.Replace("/appapi", "").Replace("https://", "").Replace("http://", "");
|
//ServerLabel.Text = "Server: " + server.Replace("/appapi", "").Replace("https://", "").Replace("http://", "");
|
||||||
|
ServerLabel.Text = "Server: " + uri.Authority;
|
||||||
|
|
||||||
await DisplayAlert("Login erfolgreich", response.Name + " " + response.Surname, "OK");
|
await DisplayAlert("Login erfolgreich", response.Name + " " + response.Surname, "OK");
|
||||||
if (Navigation.NavigationStack.Count > 1)
|
if (Navigation.NavigationStack.Count > 1)
|
||||||
await Navigation.PopAsync();
|
await Navigation.PopAsync();
|
||||||
|
else {
|
||||||
|
await Shell.Current.GoToAsync($"//StundenPage");
|
||||||
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
await DisplayAlert("Fehler", ex.Message, "OK");
|
await DisplayAlert("Fehler", ex.Message, "OK");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Aus einer URL ohne Schema eine URL mit Schema machen
|
||||||
|
/// </summary>
|
||||||
|
private static string InputUrlWithSchema(string url) {
|
||||||
|
if (!url.StartsWith("http://") && !url.StartsWith("https://")) {
|
||||||
|
url = "https://" + url;
|
||||||
|
}
|
||||||
|
if (url.StartsWith("http://")) {
|
||||||
|
url = url.Replace("http://", "https://");
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
//Zwischen manuellem und automatischem Login (mit QR-Code) umschalten und die Schalterstellung merken
|
//Zwischen manuellem und automatischem Login (mit QR-Code) umschalten und die Schalterstellung merken
|
||||||
private void Switch_Toggled(object sender, ToggledEventArgs e) {
|
private void Switch_Toggled(object sender, ToggledEventArgs e) {
|
||||||
var switcher = (Switch)sender;
|
var switcher = (Switch)sender;
|
||||||
|
|||||||
@@ -19,36 +19,53 @@
|
|||||||
|
|
||||||
<VerticalStackLayout Spacing="10" Margin="10">
|
<VerticalStackLayout Spacing="10" Margin="10">
|
||||||
|
|
||||||
|
<Label Text="{Binding SubTitle}" FontSize="Medium" FontAttributes="Bold" Margin="4,0,0,0" />
|
||||||
|
|
||||||
<Label Text="{Binding SubTitle}" FontSize="Medium" Margin="4,0,0,0" />
|
<Border>
|
||||||
|
<Border.Padding>
|
||||||
|
<OnPlatform x:TypeArguments="Thickness" Default="0,15,10,0">
|
||||||
|
<On Platform="Android" Value="0,4,10,8"/>
|
||||||
|
<On Platform="WPF" Value="0,15,10,0"/>
|
||||||
|
</OnPlatform>
|
||||||
|
</Border.Padding>
|
||||||
|
|
||||||
|
|
||||||
<Frame Padding="5,2,5,10">
|
|
||||||
<FlexLayout Direction="Row" AlignItems="Start" Wrap="Wrap" JustifyContent="SpaceBetween">
|
<FlexLayout Direction="Row" AlignItems="Start" Wrap="Wrap" JustifyContent="SpaceBetween">
|
||||||
|
<HorizontalStackLayout Spacing="10">
|
||||||
<HorizontalStackLayout>
|
<Label Text="Beginn" VerticalTextAlignment="Center" HorizontalTextAlignment="End" MinimumWidthRequest="60"></Label>
|
||||||
<Label Text="Beginn" VerticalTextAlignment="Center" HorizontalTextAlignment="End" Padding="0,0,10,0" Margin="5,0,0,0" MinimumWidthRequest="60"></Label>
|
<TimePicker x:Name="TimeBegin" HorizontalOptions="Center" Format="HH:mm" MinimumWidthRequest="80" Time="{Binding DayTime.TimeSpanVon}" />
|
||||||
<TimePicker x:Name="TimeBegin" HorizontalOptions="Center" Format="HH:mm" MinimumWidthRequest="80" Time="{Binding DayTime.TimeSpanVon}" Margin="0,0,0,-5" />
|
|
||||||
</HorizontalStackLayout>
|
</HorizontalStackLayout>
|
||||||
|
|
||||||
<HorizontalStackLayout>
|
<HorizontalStackLayout Spacing="10">
|
||||||
<Label Text="Ende" VerticalTextAlignment="Center" HorizontalTextAlignment="End" Padding="0,0,10,0" Margin="5,0,0,0" MinimumWidthRequest="60"></Label>
|
<Label Text="Ende" VerticalTextAlignment="Center" HorizontalTextAlignment="End" MinimumWidthRequest="60"></Label>
|
||||||
<TimePicker x:Name="TimeEnd" Format="HH:mm" MinimumWidthRequest="80" Time="{Binding DayTime.TimeSpanBis}" Margin="0,0,0,-5" />
|
<TimePicker x:Name="TimeEnd" Format="HH:mm" MinimumWidthRequest="80" Time="{Binding DayTime.TimeSpanBis}" />
|
||||||
</HorizontalStackLayout>
|
</HorizontalStackLayout>
|
||||||
|
|
||||||
</FlexLayout>
|
</FlexLayout>
|
||||||
</Frame>
|
</Border>
|
||||||
|
|
||||||
<Frame Padding="5,4,5,8">
|
<Border>
|
||||||
<Grid ColumnDefinitions="*,*,*">
|
<Border.Padding>
|
||||||
|
<OnPlatform x:TypeArguments="Thickness" Default="5">
|
||||||
|
<On Platform="Android" Value="5,4,5,8"/>
|
||||||
|
<On Platform="WPF" Value="5"/>
|
||||||
|
</OnPlatform>
|
||||||
|
</Border.Padding>
|
||||||
|
<!--<Grid ColumnDefinitions="*,*,*">
|
||||||
<Picker x:Name="pick_gemeinde" Title="Gemeinde" ItemsSource="{Binding OptionsGemeinde}" SelectedItem="{Binding DayTime.GemeindeAktiv, Mode=TwoWay}" ItemDisplayBinding="{Binding Name}" Grid.Column="0" IsVisible="{Binding GemeindeAktivSet}">
|
<Picker x:Name="pick_gemeinde" Title="Gemeinde" ItemsSource="{Binding OptionsGemeinde}" SelectedItem="{Binding DayTime.GemeindeAktiv, Mode=TwoWay}" ItemDisplayBinding="{Binding Name}" Grid.Column="0" IsVisible="{Binding GemeindeAktivSet}">
|
||||||
</Picker>
|
</Picker>
|
||||||
<Picker x:Name="pick_projekt" Title="Projekt" ItemsSource="{Binding OptionsProjekt}" SelectedItem="{Binding DayTime.ProjektAktiv, Mode=TwoWay}" ItemDisplayBinding="{Binding Name}" Grid.Column="1" IsVisible="{Binding ProjektAktivSet}">
|
<Picker x:Name="pick_projekt" Title="Projekt" ItemsSource="{Binding OptionsProjekt}" SelectedItem="{Binding DayTime.ProjektAktiv, Mode=TwoWay}" ItemDisplayBinding="{Binding Name}" Grid.Column="1" IsVisible="{Binding ProjektAktivSet}">
|
||||||
</Picker>
|
</Picker>
|
||||||
<Picker x:Name="pick_freistellung" Title="Freistellung" ItemsSource="{Binding OptionsFreistellung}" SelectedItem="{Binding DayTime.FreistellungAktiv, Mode=TwoWay}" ItemDisplayBinding="{Binding Name}" Grid.Column="2" IsEnabled="{Binding FreistellungEnabled}">
|
<Picker x:Name="pick_freistellung" Title="Freistellung" ItemsSource="{Binding OptionsFreistellung}" SelectedItem="{Binding DayTime.FreistellungAktiv, Mode=TwoWay}" ItemDisplayBinding="{Binding Name}" Grid.Column="2" IsEnabled="{Binding FreistellungEnabled}">
|
||||||
</Picker>
|
</Picker>
|
||||||
</Grid>
|
</Grid>-->
|
||||||
</Frame>
|
<HorizontalStackLayout>
|
||||||
|
<Picker x:Name="pick_gemeinde" Title="Gemeinde" ItemsSource="{Binding OptionsGemeinde}" SelectedItem="{Binding DayTime.GemeindeAktiv, Mode=TwoWay}" ItemDisplayBinding="{Binding Name}" IsVisible="{Binding GemeindeAktivSet}">
|
||||||
|
</Picker>
|
||||||
|
<Picker x:Name="pick_projekt" Title="Projekt" ItemsSource="{Binding OptionsProjekt}" SelectedItem="{Binding DayTime.ProjektAktiv, Mode=TwoWay}" ItemDisplayBinding="{Binding Name}" IsVisible="{Binding ProjektAktivSet}">
|
||||||
|
</Picker>
|
||||||
|
<Picker x:Name="pick_freistellung" Title="Freistellung" ItemsSource="{Binding OptionsFreistellung}" SelectedItem="{Binding DayTime.FreistellungAktiv, Mode=TwoWay}" ItemDisplayBinding="{Binding Name}" IsEnabled="{Binding FreistellungEnabled}">
|
||||||
|
</Picker>
|
||||||
|
</HorizontalStackLayout>
|
||||||
|
</Border>
|
||||||
|
|
||||||
<Editor Placeholder="Beschreibung" Text="{Binding DayTime.Description}" MinimumHeightRequest="40" AutoSize="TextChanges" FontSize="18" />
|
<Editor Placeholder="Beschreibung" Text="{Binding DayTime.Description}" MinimumHeightRequest="40" AutoSize="TextChanges" FontSize="18" />
|
||||||
|
|
||||||
@@ -66,9 +83,8 @@
|
|||||||
<Label>
|
<Label>
|
||||||
<Label.FormattedText>
|
<Label.FormattedText>
|
||||||
<FormattedString>
|
<FormattedString>
|
||||||
<Span Text="Am " />
|
<Span Text="Vorhandene Einträge: " />
|
||||||
<Span Text="{Binding SubTitle}" />
|
<Span Text="{Binding SubTitle}" />
|
||||||
<Span Text=" vorhandene Einträge:"/>
|
|
||||||
</FormattedString>
|
</FormattedString>
|
||||||
</Label.FormattedText>
|
</Label.FormattedText>
|
||||||
</Label>
|
</Label>
|
||||||
|
|||||||
@@ -1,32 +1,54 @@
|
|||||||
|
using CommunityToolkit.Maui.Alerts;
|
||||||
|
using CommunityToolkit.Maui.Core;
|
||||||
|
using Jugenddienst_Stunden.Models;
|
||||||
using Jugenddienst_Stunden.ViewModels;
|
using Jugenddienst_Stunden.ViewModels;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
|
|
||||||
namespace Jugenddienst_Stunden.Views;
|
namespace Jugenddienst_Stunden.Views;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Einzelner Stundeneintrag
|
||||||
|
/// </summary>
|
||||||
public partial class StundePage : ContentPage {
|
public partial class StundePage : ContentPage {
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// CTOR
|
/// CTOR
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public StundePage() {
|
public StundePage() {
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
if (BindingContext is StundeViewModel vm) {
|
|
||||||
vm.AlertEvent += Vm_AlertEvent;
|
|
||||||
//vm.InfoEvent += Vm_InfoEvent;
|
|
||||||
vm.ConfirmEvent += ShowConfirm;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
if (BindingContext is StundeViewModel vm) {
|
||||||
|
vm.AlertEvent += Vm_AlertEvent;
|
||||||
|
vm.InfoEvent += Vm_InfoEvent;
|
||||||
|
vm.ConfirmEvent += ShowConfirm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void Vm_AlertEvent(object? sender, string e) {
|
private void Vm_AlertEvent(object? sender, string e) {
|
||||||
DisplayAlert("Fehler:", e, "OK");
|
DisplayAlert("Fehler:", e, "OK");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task<bool> ShowConfirm(string title, string message) {
|
||||||
|
return await DisplayAlert(title, message, "Passt!", "Na, nor decht nit.");
|
||||||
|
}
|
||||||
|
|
||||||
private async Task<bool> ShowConfirm(string title, string message) {
|
private void Vm_InfoEvent(object? sender, string e) {
|
||||||
return await DisplayAlert(title, message, "Passt!", "Na, nor decht nit.");
|
MainThread.BeginInvokeOnMainThread(async () => {
|
||||||
}
|
CancellationTokenSource cts = new CancellationTokenSource();
|
||||||
|
ToastDuration duration = ToastDuration.Short;
|
||||||
|
double fontSize = 20;
|
||||||
|
var toast = Toast.Make(e, duration, fontSize);
|
||||||
|
await toast.Show(cts.Token);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//private async Task<bool> ShowConfirm(string title, string message, string ok, string not_ok) {
|
||||||
|
// return await DisplayAlert(title, message, ok, not_ok);
|
||||||
|
//}
|
||||||
|
|
||||||
|
//private async void ShowConfirm(object? sender, ConfirmEventArgs e) {
|
||||||
|
// bool result = await DisplayAlert(e.Title, e.Message, e.Ok, e.NotOk);
|
||||||
|
// e.Result = result;
|
||||||
|
//}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||||
xmlns:models="clr-namespace:Jugenddienst_Stunden.ViewModels"
|
|
||||||
xmlns:mmodels="clr-namespace:Jugenddienst_Stunden.Models"
|
xmlns:mmodels="clr-namespace:Jugenddienst_Stunden.Models"
|
||||||
|
xmlns:models="clr-namespace:Jugenddienst_Stunden.ViewModels"
|
||||||
|
xmlns:conv="clr-namespace:Jugenddienst_Stunden.Converter"
|
||||||
x:Class="Jugenddienst_Stunden.Views.StundenPage"
|
x:Class="Jugenddienst_Stunden.Views.StundenPage"
|
||||||
Title="{Binding Title}">
|
Title="{Binding Title}">
|
||||||
|
|
||||||
@@ -11,12 +12,16 @@
|
|||||||
</ContentPage.BindingContext>
|
</ContentPage.BindingContext>
|
||||||
|
|
||||||
<ContentPage.Resources>
|
<ContentPage.Resources>
|
||||||
<FontImageSource x:Key="ToolbarIcon"
|
<ResourceDictionary>
|
||||||
|
<conv:SecondsTimeConverter x:Key="secToTime" />
|
||||||
|
<FontImageSource x:Key="ToolbarIcon"
|
||||||
Glyph="+"
|
Glyph="+"
|
||||||
Size="22"
|
Size="22"
|
||||||
Color="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource White}}"/>
|
Color="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource White}}"/>
|
||||||
|
</ResourceDictionary>
|
||||||
</ContentPage.Resources>
|
</ContentPage.Resources>
|
||||||
|
|
||||||
|
|
||||||
<ContentPage.ToolbarItems>
|
<ContentPage.ToolbarItems>
|
||||||
<!--<ToolbarItem Text="Lade Liste" Command="{Binding RefreshListCommand}"/>-->
|
<!--<ToolbarItem Text="Lade Liste" Command="{Binding RefreshListCommand}"/>-->
|
||||||
<ToolbarItem Text="Neuer Eintrag" IconImageSource="{StaticResource ToolbarIcon}" Command="{Binding NewEntryCommand}" />
|
<ToolbarItem Text="Neuer Eintrag" IconImageSource="{StaticResource ToolbarIcon}" Command="{Binding NewEntryCommand}" />
|
||||||
@@ -93,9 +98,9 @@
|
|||||||
<Setter Property="Padding" Value="4"/>
|
<Setter Property="Padding" Value="4"/>
|
||||||
</DataTrigger>
|
</DataTrigger>
|
||||||
</HorizontalStackLayout.Triggers>
|
</HorizontalStackLayout.Triggers>
|
||||||
<Label Text="{Binding GemeindeAktiv.Name}" IsVisible="{Binding Source={RelativeSource AncestorType={x:Type ContentPage}}, Path=BindingContext.GemeindeAktivSet}" />
|
<Label Text="{Binding GemeindeAktiv.Name}" Margin="0,0,10,0" IsVisible="{Binding Source={RelativeSource AncestorType={x:Type ContentPage}}, Path=BindingContext.GemeindeAktivSet}" />
|
||||||
<Label Text="{Binding ProjektAktiv.Name}" Margin="10,0,0,0" IsVisible="{Binding Source={RelativeSource AncestorType={x:Type ContentPage}}, Path=BindingContext.ProjektAktivSet}" />
|
<Label Text="{Binding ProjektAktiv.Name}" Margin="0,0,10,0" IsVisible="{Binding Source={RelativeSource AncestorType={x:Type ContentPage}}, Path=BindingContext.ProjektAktivSet}" />
|
||||||
<Label Text="{Binding FreistellungAktiv.Name}" Margin="10,0,0,0" />
|
<Label Text="{Binding FreistellungAktiv.Name}" IsVisible="{Binding Approved}" />
|
||||||
</HorizontalStackLayout>
|
</HorizontalStackLayout>
|
||||||
|
|
||||||
<Label Text="{Binding Description}" Padding="0,0,0,15"/>
|
<Label Text="{Binding Description}" Padding="0,0,0,15"/>
|
||||||
@@ -108,7 +113,7 @@
|
|||||||
<BoxView HeightRequest="1" />
|
<BoxView HeightRequest="1" />
|
||||||
|
|
||||||
<Button Text="{Binding LoadOverview}" Command="{Binding LoadDataCommand}" />
|
<Button Text="{Binding LoadOverview}" Command="{Binding LoadDataCommand}" />
|
||||||
<Frame Padding="2" HeightRequest="125">
|
<Border Padding="2" HeightRequest="125">
|
||||||
<Grid RowDefinitions="Auto,Auto,Auto,Auto,Auto,*" ColumnDefinitions="Auto,*" Margin="10,2">
|
<Grid RowDefinitions="Auto,Auto,Auto,Auto,Auto,*" ColumnDefinitions="Auto,*" Margin="10,2">
|
||||||
<Label Grid.Row="0" Text="Soll:" />
|
<Label Grid.Row="0" Text="Soll:" />
|
||||||
<Label Grid.Row="1" Text="Summe:" />
|
<Label Grid.Row="1" Text="Summe:" />
|
||||||
@@ -117,13 +122,13 @@
|
|||||||
<Label Grid.Row="4" Text="Restüberstunden:" />
|
<Label Grid.Row="4" Text="Restüberstunden:" />
|
||||||
<Label Grid.Row="5" Text="Resturlaub:" />
|
<Label Grid.Row="5" Text="Resturlaub:" />
|
||||||
|
|
||||||
<Label Grid.Row="0" Grid.Column="1" HorizontalTextAlignment="End" Padding="0,0,5,0" Text="{Binding Nominal}" ToolTipProperties.Text="Sollstunden" />
|
<Label Grid.Row="0" Grid.Column="1" HorizontalTextAlignment="End" Padding="0,0,5,0" Text="{Binding Nominal, Converter={StaticResource secToTime}}" ToolTipProperties.Text="Sollstunden" />
|
||||||
<Label Grid.Row="1" Grid.Column="1" HorizontalTextAlignment="End" Padding="0,0,5,0" Text="{Binding ZeitCalculated}" ToolTipProperties.Text="Geleistete Stunden" />
|
<Label Grid.Row="1" Grid.Column="1" HorizontalTextAlignment="End" Padding="0,0,5,0" Text="{Binding ZeitCalculated, Converter={StaticResource secToTime}}" ToolTipProperties.Text="Geleistete Stunden" />
|
||||||
<Label Grid.Row="2" Grid.Column="1" HorizontalTextAlignment="End" Padding="0,0,5,0" Text="{Binding OvertimeMonth}" />
|
<Label Grid.Row="2" Grid.Column="1" HorizontalTextAlignment="End" Padding="0,0,5,0" Text="{Binding OvertimeMonth, Converter={StaticResource secToTime}}" />
|
||||||
<Label Grid.Row="4" Grid.Column="1" HorizontalTextAlignment="End" Padding="0,0,5,0" Text="{Binding Overtime}" />
|
<Label Grid.Row="4" Grid.Column="1" HorizontalTextAlignment="End" Padding="0,0,5,0" Text="{Binding Overtime, Converter={StaticResource secToTime}}" />
|
||||||
<Label Grid.Row="5" Grid.Column="1" HorizontalTextAlignment="End" Padding="0,0,5,0" Text="{Binding Holiday}" />
|
<Label Grid.Row="5" Grid.Column="1" HorizontalTextAlignment="End" Padding="0,0,5,0" Text="{Binding Holiday, Converter={StaticResource secToTime}}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</Frame>
|
</Border>
|
||||||
|
|
||||||
</VerticalStackLayout>
|
</VerticalStackLayout>
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
using Jugenddienst_Stunden.ViewModels;
|
using Jugenddienst_Stunden.ViewModels;
|
||||||
using Jugenddienst_Stunden.Models;
|
using Jugenddienst_Stunden.Models;
|
||||||
|
using CommunityToolkit.Maui.Core;
|
||||||
|
using CommunityToolkit.Maui.Alerts;
|
||||||
|
|
||||||
namespace Jugenddienst_Stunden.Views;
|
namespace Jugenddienst_Stunden.Views;
|
||||||
|
|
||||||
@@ -41,9 +43,21 @@ public partial class StundenPage : ContentPage {
|
|||||||
await DisplayAlert("Fehler:", e, "OK");
|
await DisplayAlert("Fehler:", e, "OK");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
//private void Vm_InfoEvent(object? sender, string e) {
|
||||||
|
// DisplayAlert("Information:", e, "OK");
|
||||||
|
//}
|
||||||
|
//private void Vm_InfoEvent(object? sender, string e) {
|
||||||
|
// MainThread.BeginInvokeOnMainThread(async () => {
|
||||||
|
// await DisplayAlert("Information:", e, "OK");
|
||||||
|
// });
|
||||||
|
//}
|
||||||
private void Vm_InfoEvent(object? sender, string e) {
|
private void Vm_InfoEvent(object? sender, string e) {
|
||||||
MainThread.BeginInvokeOnMainThread(async () => {
|
MainThread.BeginInvokeOnMainThread(async () => {
|
||||||
await DisplayAlert("Information:", e, "OK");
|
CancellationTokenSource cts = new CancellationTokenSource();
|
||||||
|
ToastDuration duration = ToastDuration.Short;
|
||||||
|
double fontSize = 20;
|
||||||
|
var toast = Toast.Make(e, duration, fontSize);
|
||||||
|
await toast.Show(cts.Token);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user