From b9d557642cfe67257bbdec885aa1f0a1b72c84ac Mon Sep 17 00:00:00 2001 From: Rene Evertz Date: Wed, 6 May 2026 15:57:24 +0200 Subject: [PATCH 01/70] AiRoutinen View+AddEditDelete MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Wer reitet so spät durch Nacht und Wind? Es ist der Vater mit seinem Kind; Er hat den Knaben wohn in dem Arm, Er faβt ihn sicher, er hält ihn warm. --- BeWo/BeWo.csproj | 9 + .../GeneratedAiEnhancedService.cs | 30 + BeWo/Services/BeWoWindowService.cs | 14 + BeWo/Styles/DataTemplates/DataTemplates.xaml | 56 +- BeWo/View/BeWoFileView.xaml | 77 ++- .../AiPromptbausteinComplexSelectionView.xaml | 8 +- .../AI/AiPromptbausteinComplexTreeView.xaml | 602 ++++++++++++++---- .../AiPromptbausteinComplexTreeView.xaml.cs | 39 +- .../AI/AiPromptbausteinRoutineView.xaml | 195 ++++++ .../AI/AiPromptbausteinRoutineView.xaml.cs | 93 +++ ...romptbausteinFolderItemTemplateSelector.cs | 29 + BeWo/ViewModel/AiPromptbausteinFolderVM.cs | 103 ++- BeWo/ViewModel/AiPromptbausteinRoutineVM.cs | 24 +- ...PromptbausteinComplexSelectionViewModel.cs | 28 +- .../AiPromptbausteinComplexTreeViewModel.cs | 141 +++- .../AiPromptbausteinRoutineViewModel.cs | 49 ++ Service/Plugins/AiPromptbausteineService.cs | 60 +- .../Enhanced/IAiEnhancedService.cs | 17 +- .../Enhanced/AiEnhancedServiceImp.cs | 9 + .../Feature/AI/AiPromptbausteinFolderDC.cs | 2 + 20 files changed, 1365 insertions(+), 220 deletions(-) create mode 100644 BeWo/View/Detail/AI/AiPromptbausteinRoutineView.xaml create mode 100644 BeWo/View/Detail/AI/AiPromptbausteinRoutineView.xaml.cs create mode 100644 BeWo/View/TemplateSelectors/AiPromptbausteinFolderItemTemplateSelector.cs create mode 100644 BeWo/ViewModel/View/Administration/AiPromptbausteinRoutineViewModel.cs diff --git a/BeWo/BeWo.csproj b/BeWo/BeWo.csproj index 8ed9d7433..a7539b52a 100644 --- a/BeWo/BeWo.csproj +++ b/BeWo/BeWo.csproj @@ -165,6 +165,7 @@ + @@ -205,6 +206,9 @@ AiConfigView.xaml + + AiPromptbausteinRoutineView.xaml + DatenbereinigungView.xaml @@ -216,6 +220,7 @@ + AnimatedBeWoWindow.xaml @@ -343,6 +348,10 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + MSBuild:Compile Designer diff --git a/BeWo/ServiceProxy/GeneratedAiEnhancedService.cs b/BeWo/ServiceProxy/GeneratedAiEnhancedService.cs index c90adc2e7..c17dfc380 100644 --- a/BeWo/ServiceProxy/GeneratedAiEnhancedService.cs +++ b/BeWo/ServiceProxy/GeneratedAiEnhancedService.cs @@ -75,6 +75,11 @@ namespace BeWo.ServiceProxy [System.ServiceModel.FaultContractAttribute(typeof(BS.Shared.Core.BeWoFault), Action="http://tempuri.org/IAiEnhancedService/InsertAiPromptbausteinPromptBeWoFaultFault", Name="BeWoFault", Namespace="http://schemas.datacontract.org/2004/07/BS.Shared.Core")] System.Collections.Generic.List InsertAiPromptbausteinPrompt(System.Collections.Generic.List prompts); + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IAiEnhancedService/InsertAiPromptbausteinRoutine", ReplyAction="http://tempuri.org/IAiEnhancedService/InsertAiPromptbausteinRoutineResponse")] + [System.ServiceModel.FaultContractAttribute(typeof(BS.Shared.Core.BeWoFault), Action="http://tempuri.org/IAiEnhancedService/InsertAiPromptbausteinRoutineBeWoFaultFault" + + "", Name="BeWoFault", Namespace="http://schemas.datacontract.org/2004/07/BS.Shared.Core")] + System.Collections.Generic.List InsertAiPromptbausteinRoutine(System.Collections.Generic.List routine); + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IAiEnhancedService/UpdateAiPromptbausteinFolder", ReplyAction="http://tempuri.org/IAiEnhancedService/UpdateAiPromptbausteinFolderResponse")] [System.ServiceModel.FaultContractAttribute(typeof(BS.Shared.Core.BeWoFault), Action="http://tempuri.org/IAiEnhancedService/UpdateAiPromptbausteinFolderBeWoFaultFault", Name="BeWoFault", Namespace="http://schemas.datacontract.org/2004/07/BS.Shared.Core")] System.Collections.Generic.List UpdateAiPromptbausteinFolder(System.Collections.Generic.List folders); @@ -83,6 +88,11 @@ namespace BeWo.ServiceProxy [System.ServiceModel.FaultContractAttribute(typeof(BS.Shared.Core.BeWoFault), Action="http://tempuri.org/IAiEnhancedService/UpdateAiPromptbausteinPromptBeWoFaultFault", Name="BeWoFault", Namespace="http://schemas.datacontract.org/2004/07/BS.Shared.Core")] System.Collections.Generic.List UpdateAiPromptbausteinPrompt(System.Collections.Generic.List prompts); + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IAiEnhancedService/UpdateAiPromptbausteinRoutine", ReplyAction="http://tempuri.org/IAiEnhancedService/UpdateAiPromptbausteinRoutineResponse")] + [System.ServiceModel.FaultContractAttribute(typeof(BS.Shared.Core.BeWoFault), Action="http://tempuri.org/IAiEnhancedService/UpdateAiPromptbausteinRoutineBeWoFaultFault" + + "", Name="BeWoFault", Namespace="http://schemas.datacontract.org/2004/07/BS.Shared.Core")] + System.Collections.Generic.List UpdateAiPromptbausteinRoutine(System.Collections.Generic.List routine); + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IAiEnhancedService/DeleteAiPromptbausteinFolder", ReplyAction="http://tempuri.org/IAiEnhancedService/DeleteAiPromptbausteinFolderResponse")] [System.ServiceModel.FaultContractAttribute(typeof(BS.Shared.Core.BeWoFault), Action="http://tempuri.org/IAiEnhancedService/DeleteAiPromptbausteinFolderBeWoFaultFault", Name="BeWoFault", Namespace="http://schemas.datacontract.org/2004/07/BS.Shared.Core")] void DeleteAiPromptbausteinFolder(System.Collections.Generic.Dictionary oid2version); @@ -91,6 +101,11 @@ namespace BeWo.ServiceProxy [System.ServiceModel.FaultContractAttribute(typeof(BS.Shared.Core.BeWoFault), Action="http://tempuri.org/IAiEnhancedService/DeleteAiPromptbausteinPromptBeWoFaultFault", Name="BeWoFault", Namespace="http://schemas.datacontract.org/2004/07/BS.Shared.Core")] void DeleteAiPromptbausteinPrompt(System.Collections.Generic.Dictionary oid2version); + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IAiEnhancedService/DeleteAiPromptbausteinRoutine", ReplyAction="http://tempuri.org/IAiEnhancedService/DeleteAiPromptbausteinRoutineResponse")] + [System.ServiceModel.FaultContractAttribute(typeof(BS.Shared.Core.BeWoFault), Action="http://tempuri.org/IAiEnhancedService/DeleteAiPromptbausteinRoutineBeWoFaultFault" + + "", Name="BeWoFault", Namespace="http://schemas.datacontract.org/2004/07/BS.Shared.Core")] + void DeleteAiPromptbausteinRoutine(System.Collections.Generic.Dictionary oid2version); + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IAiEnhancedService/ExecuteAiFunctionServiceRecordDocumentation" + "", ReplyAction="http://tempuri.org/IAiEnhancedService/ExecuteAiFunctionServiceRecordDocumentation" + "Response")] @@ -211,6 +226,11 @@ namespace BeWo.ServiceProxy return base.Channel.InsertAiPromptbausteinPrompt(prompts); } + public System.Collections.Generic.List InsertAiPromptbausteinRoutine(System.Collections.Generic.List routine) + { + return base.Channel.InsertAiPromptbausteinRoutine(routine); + } + public System.Collections.Generic.List UpdateAiPromptbausteinFolder(System.Collections.Generic.List folders) { return base.Channel.UpdateAiPromptbausteinFolder(folders); @@ -221,6 +241,11 @@ namespace BeWo.ServiceProxy return base.Channel.UpdateAiPromptbausteinPrompt(prompts); } + public System.Collections.Generic.List UpdateAiPromptbausteinRoutine(System.Collections.Generic.List routine) + { + return base.Channel.UpdateAiPromptbausteinRoutine(routine); + } + public void DeleteAiPromptbausteinFolder(System.Collections.Generic.Dictionary oid2version) { base.Channel.DeleteAiPromptbausteinFolder(oid2version); @@ -231,6 +256,11 @@ namespace BeWo.ServiceProxy base.Channel.DeleteAiPromptbausteinPrompt(oid2version); } + public void DeleteAiPromptbausteinRoutine(System.Collections.Generic.Dictionary oid2version) + { + base.Channel.DeleteAiPromptbausteinRoutine(oid2version); + } + public BS.Shared.DataContracts.Feature.AI.Functions.ServiceRecords.AiFunctionDocResponse ExecuteAiFunctionServiceRecordDocumentation(BS.Shared.DataContracts.Feature.AI.Functions.ServiceRecords.AiFunctionDocRequest request) { return base.Channel.ExecuteAiFunctionServiceRecordDocumentation(request); diff --git a/BeWo/Services/BeWoWindowService.cs b/BeWo/Services/BeWoWindowService.cs index 978aff5d1..b2070620c 100644 --- a/BeWo/Services/BeWoWindowService.cs +++ b/BeWo/Services/BeWoWindowService.cs @@ -68,6 +68,10 @@ namespace BeWo.Services { ShowAiPromptbausteinSelectionComplexWindow(viewModel6); } + else if (windowViewModel is AiPromptbausteinRoutineViewModel viewModel7) + { + ShowAiPromptbausteinRoutineWindow(viewModel7); + } else { throw new NotImplementedException($"type not implemented: {typeof(T)}"); @@ -105,6 +109,16 @@ namespace BeWo.Services }; Show("KI Promptbaustein Prompt", control, viewModel, options); } + public void ShowAiPromptbausteinRoutineWindow(AiPromptbausteinRoutineViewModel viewModel) + { + var control = new AiPromptbausteinRoutineView(viewModel); + var options = new BeWoWindowOptions() + { + Height = 400, + Width = 600 + }; + Show("KI Promptbaustein Prompt", control, viewModel, options); + } public void ShowAiPromptbausteinActionResultWindow(AiPromptbausteinActionResultViewModel viewModel) { var control = new AiPromptbausteinActionResultView(viewModel); diff --git a/BeWo/Styles/DataTemplates/DataTemplates.xaml b/BeWo/Styles/DataTemplates/DataTemplates.xaml index 71f5c2d98..f39d699df 100644 --- a/BeWo/Styles/DataTemplates/DataTemplates.xaml +++ b/BeWo/Styles/DataTemplates/DataTemplates.xaml @@ -12,14 +12,25 @@ ItemsSource="{Binding Path=SubFolders.VMList}"> + + + + @@ -48,6 +59,49 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/BeWo/View/BeWoFileView.xaml b/BeWo/View/BeWoFileView.xaml index 4b06691b2..4f19b2d73 100644 --- a/BeWo/View/BeWoFileView.xaml +++ b/BeWo/View/BeWoFileView.xaml @@ -37,7 +37,10 @@ - + @@ -54,7 +57,6 @@ Height="20" Source="..\Ressources\Icons\Folder.png" Stretch="Fill" /> - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/BeWo/View/Detail/AI/AiPromptbausteinComplexSelectionView.xaml b/BeWo/View/Detail/AI/AiPromptbausteinComplexSelectionView.xaml index a11947ac0..011631be4 100644 --- a/BeWo/View/Detail/AI/AiPromptbausteinComplexSelectionView.xaml +++ b/BeWo/View/Detail/AI/AiPromptbausteinComplexSelectionView.xaml @@ -60,6 +60,7 @@ Padding="4,16,4,16" AllowDrop="True" ContextMenuOpening="treeView_ContextMenuOpening" + ContextMenuService.IsEnabled="{Binding CanOpenContextMenu}" ItemContainerStyle="{DynamicResource igoal_treeitemstyle}" ItemTemplate="{StaticResource ai_promptbaustein_folder_itemtemplate}" ItemsSource="{Binding Folders.VMList, UpdateSourceTrigger=PropertyChanged}" @@ -122,6 +123,7 @@ VerticalContentAlignment="Stretch" AllowDrop="False" ContextMenuOpening="ListBox_ContextMenuOpening" + ContextMenuService.IsEnabled="{Binding CanOpenContextMenu}" EditValue="{Binding SelectedPrompt, Mode=TwoWay}" ItemContainerStyle="{StaticResource PromptListBoxItem}" ItemsSource="{Binding SelectedFolder.Prompts, UpdateSourceTrigger=PropertyChanged}" @@ -300,10 +302,10 @@ Style="{StaticResource ObjectEditGroupBox}"> + Content="{Binding AcceptButtonText}" + Style="{StaticResource PrimaryButton}" /> diff --git a/BeWo/View/Detail/AI/AiPromptbausteinComplexTreeView.xaml b/BeWo/View/Detail/AI/AiPromptbausteinComplexTreeView.xaml index daa1cbe06..0a425bf45 100644 --- a/BeWo/View/Detail/AI/AiPromptbausteinComplexTreeView.xaml +++ b/BeWo/View/Detail/AI/AiPromptbausteinComplexTreeView.xaml @@ -9,6 +9,7 @@ xmlns:dxlc="http://schemas.devexpress.com/winfx/2008/xaml/layoutcontrol" xmlns:local1="clr-namespace:BeWo.View.Detail.AI" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:templateselectors="clr-namespace:BeWo.View.TemplateSelectors" xmlns:view="clr-namespace:BeWo.View" xmlns:vm="clr-namespace:BeWo.ViewModel" d:DataContext="{d:DesignInstance Type=administration:AiPromptbausteinComplexTreeViewModel, @@ -27,6 +28,256 @@ TargetType="ListBoxItem"> + + + + + + + + + + + + + + + + + + + + + + + + + (i) + + + + + + + + + Bearbeitet vor x Minuten + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + (i) + + + + + + + + + 3 Schritte · 2 min + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -57,8 +308,10 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (i) - - - - - - - + Padding="0" + BorderThickness="0,1,1,1" + BorderBrush="Gray" + SelectionChanged="TabControl_SelectionChanged"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BeWo/View/Detail/AI/AiPromptbausteinComplexTreeView.xaml.cs b/BeWo/View/Detail/AI/AiPromptbausteinComplexTreeView.xaml.cs index abdd2fc31..fe74b91d1 100644 --- a/BeWo/View/Detail/AI/AiPromptbausteinComplexTreeView.xaml.cs +++ b/BeWo/View/Detail/AI/AiPromptbausteinComplexTreeView.xaml.cs @@ -118,38 +118,9 @@ namespace BeWo.View.Detail.AI private void ListBox_ContextMenuOpening(object sender, ContextMenuEventArgs e) { ViewModel.UpdatePromptCommands(); - favorite.Header = (ViewModel.SelectedPrompt?.IsFavorite ?? false) ? "Favorit entfernen" : "Favorit hinzufügen"; + favorite.Header = ((ViewModel.SelectedItem as AiPromptbausteinPromptVM)?.IsFavorite ?? false) ? "Favorit entfernen" : "Favorit hinzufügen"; } - //private void listBox_Prompts_PreviewMouseUp(object sender, MouseButtonEventArgs e) - //{ - // IsDragging = false; - //} - - //private void listBox_Prompts_Drop(object sender, DragEventArgs e) - //{ - // HitTestResult hitTest = VisualTreeHelper.HitTest(listBoxEdit1, e.GetPosition(listBoxEdit1)); - // ListBoxEditItem item = LayoutHelper.FindParentObject((DependencyObject)hitTest.VisualHit); - // int insertIndex = ViewModel.SelectedFolder.SubPrompts.VMList.IndexOf((AiPromptbausteinPromptVM)item.Content); - // ViewModel.SelectedFolder.SubPrompts.VMList.Remove((AiPromptbausteinPromptVM)e.Data.GetData(typeof(AiPromptbausteinPromptVM))); - // if (listBoxEdit1.SelectedIndex > insertIndex) - // insertIndex++; - // ViewModel.SelectedFolder.SubPrompts.VMList.Insert(insertIndex, (AiPromptbausteinPromptVM)e.Data.GetData(typeof(AiPromptbausteinPromptVM))); - //} - - //private void listBox_Prompts_DragOver(object sender, DragEventArgs e) - //{ - // e.Effects = DragDropEffects.Move; - //} - - //private void listBox_Prompts_MouseMove(object sender, MouseEventArgs e) - //{ - // if (IsDragging && listBoxEdit1.SelectedItem != null) - // { - // DragDrop.DoDragDrop(listBoxEdit1, listBoxEdit1.SelectedItem, DragDropEffects.Move); - // } - //} - private void Hyperlink_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e) { Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri)); @@ -167,5 +138,13 @@ namespace BeWo.View.Detail.AI e.Handled = true; } } + + private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + if(e.OriginalSource is TabControl) + { + ViewModel.SelectedItem = null; + } + } } } diff --git a/BeWo/View/Detail/AI/AiPromptbausteinRoutineView.xaml b/BeWo/View/Detail/AI/AiPromptbausteinRoutineView.xaml new file mode 100644 index 000000000..740976afa --- /dev/null +++ b/BeWo/View/Detail/AI/AiPromptbausteinRoutineView.xaml @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BeWo/View/Detail/AI/AiPromptbausteinRoutineView.xaml.cs b/BeWo/View/Detail/AI/AiPromptbausteinRoutineView.xaml.cs new file mode 100644 index 000000000..7b990942d --- /dev/null +++ b/BeWo/View/Detail/AI/AiPromptbausteinRoutineView.xaml.cs @@ -0,0 +1,93 @@ +using BeWo.ViewModel; +using BeWo.ViewModel.ListViewModel; +using BeWo.ViewModel.View.Administration; +using BeWo.ViewModel.View.AI; +using BS.Shared.DataContracts.Feature.AI; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace BeWo.View.Detail.AI +{ + /// + /// Interaktionslogik für AiPromptbausteinRoutineView.xaml + /// + public partial class AiPromptbausteinRoutineView : UserControl + { + //public static readonly DependencyProperty RoutineProperty = + // DependencyProperty.Register("Routine", typeof(AiPromptbausteinRoutineVM), typeof(AiPromptbausteinRoutineView), new PropertyMetadata(null)); + + //public static readonly DependencyProperty FolderListVMProperty = + // DependencyProperty.Register("FolderListVM", typeof(AiPromptbausteinFolderListVM), typeof(AiPromptbausteinRoutineView), new PropertyMetadata(null)); + + //public AiPromptbausteinRoutineVM Routine + //{ + // get { return (AiPromptbausteinRoutineVM)GetValue(RoutineProperty); } + // set { SetValue(RoutineProperty, value); } + //} + + //public AiPromptbausteinFolderListVM FolderListVM + //{ + // get { return (AiPromptbausteinFolderListVM)GetValue(FolderListVMProperty); } + // set { SetValue(FolderListVMProperty, value); } + //} + + public AiPromptbausteinRoutineViewModel ViewModel { get; set; } + + public AiPromptbausteinRoutineView(AiPromptbausteinRoutineViewModel viewmodel) + { + InitializeComponent(); + + DataContext = ViewModel = viewmodel; + + var viewmodel2 = new AiPromptbausteinSelectionComplexViewModel(ViewModel.ViewModel.ActionType, ViewModel.FolderListVM, false, false); + var control = new AiPromptbausteinComplexSelectionView(viewmodel2); + + viewmodel2.PromptAccepted += (s, e) => + { + if (e is null) + return; + + if (e.DataContract.Version is null) + { + MessageBox.Show("Es können keine Promptbausteine hinzugefügt werden, die noch nicht gespeichert wurden. Speichern Sie bitte zuvor."); + return; + } + + var step = new AiPromptbausteinRoutineStepDC(); + step.PromptReference = e.DataContract; + step.ReferenceVersion = e.DataContract.Version.Value; + var step_vm = new AiPromptbausteinRoutineStepVM(step); + + ViewModel.ViewModel.Steps.VMList.Add(step_vm); + myPopup.IsOpen = false; + }; + + myPopupBorder.Child = control; + } + + private void Button_Plus_Click(object sender, RoutedEventArgs e) + { + myPopup.IsOpen = true; + } + + private void Button_Minus_Click(object sender, RoutedEventArgs e) + { + if (!(steps.SelectedItem is AiPromptbausteinRoutineStepVM step)) + return; + + ViewModel.ViewModel.Steps.VMList.Remove(step); + } + } +} diff --git a/BeWo/View/TemplateSelectors/AiPromptbausteinFolderItemTemplateSelector.cs b/BeWo/View/TemplateSelectors/AiPromptbausteinFolderItemTemplateSelector.cs new file mode 100644 index 000000000..acfd674b9 --- /dev/null +++ b/BeWo/View/TemplateSelectors/AiPromptbausteinFolderItemTemplateSelector.cs @@ -0,0 +1,29 @@ +using BeWo.ViewModel; +using DevExpress.Web.Internal.XmlProcessor; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; + +namespace BeWo.View.TemplateSelectors +{ + public class AiPromptbausteinFolderItemTemplateSelector : DataTemplateSelector + { + public DataTemplate AiPromptbausteinPromptTemplate { get; set; } + public DataTemplate AiPromptbausteinRoutineTemplate { get; set; } + + public override DataTemplate SelectTemplate(object item, DependencyObject container) + { + if (item is AiPromptbausteinPromptVM prompt) + return AiPromptbausteinPromptTemplate; + + if (item is AiPromptbausteinRoutineVM routine) + return AiPromptbausteinRoutineTemplate; + + throw new NotImplementedException("item is not AiPromptbausteinPromptVM or AiPromptbausteinRoutineVM"); + } + } +} diff --git a/BeWo/ViewModel/AiPromptbausteinFolderVM.cs b/BeWo/ViewModel/AiPromptbausteinFolderVM.cs index 306f9f6df..debd70390 100644 --- a/BeWo/ViewModel/AiPromptbausteinFolderVM.cs +++ b/BeWo/ViewModel/AiPromptbausteinFolderVM.cs @@ -22,6 +22,7 @@ namespace BeWo.ViewModel private AiActionType _ActionType; private AiPromptbausteinFolderListVM _SubFolders; private AiPromptbausteinPromptListVM _SubPrompts; + private AiPromptbausteinRoutineListVM _SubRoutines; public AiPromptbausteinFolderVM(AiPromptbausteinFolderDC dc) : base(dc, dc.Oid) { @@ -36,8 +37,6 @@ namespace BeWo.ViewModel var success = SetProperty(ref _Title, value, nameof(Title), () => DataContract.Title); if (!success) return; - - FirePropertyChanged(nameof(Displayname)); } } @@ -99,7 +98,8 @@ namespace BeWo.ViewModel return; _SubPrompts.VMList.ListChanged += (s, e) => { - FirePropertyChanged(nameof(Displayname)); + FirePropertyChanged(nameof(TotalPromptCount)); + FirePropertyChanged(nameof(AlleFolderItems)); if (e.ListChangedType == System.ComponentModel.ListChangedType.ItemChanged) return; @@ -109,6 +109,40 @@ namespace BeWo.ViewModel } } + public AiPromptbausteinRoutineListVM SubRoutines + { + get => _SubRoutines; + set + { + var success = SetProperty(ref _SubRoutines, value, nameof(SubRoutines)); + if (!success) + return; + + _SubRoutines.VMList.ListChanged += (s, e) => { + FirePropertyChanged(nameof(TotalRoutineCount)); + FirePropertyChanged(nameof(AlleFolderItems)); + + if (e.ListChangedType == System.ComponentModel.ListChangedType.ItemChanged) + return; + + FirePropertyChanged(nameof(Routines)); + }; + } + } + + public List AlleFolderItems + { + get + { + var l1 = Prompts.Cast(); + var l2 = Routines.Cast(); + + var l12 = l1.Union(l2); + + return l12.ToList(); + } + } + public List Prompts { get @@ -126,6 +160,23 @@ namespace BeWo.ViewModel } } + public List Routines + { + get + { + var res = new List(); + + res.AddRange(SubRoutines.VMList); + + foreach (var folder in SubFolders.VMList) + { + res.AddRange(folder.Routines); + } + + return res; + } + } + public bool CanAddFolder { get => DataContract.CanAddFolder; @@ -136,6 +187,11 @@ namespace BeWo.ViewModel get => DataContract.CanAddPrompt; set => DataContract.CanAddPrompt = value; } + public bool CanAddRoutine + { + get => DataContract.CanAddRoutine; + set => DataContract.CanAddRoutine = value; + } public bool CanEdit { get => DataContract.CanEdit && BeWoApp.HasLoggedOnUserRight(UserRightType.AiModulePromptbausteineEdit); @@ -155,18 +211,18 @@ namespace BeWo.ViewModel public FontWeight FontWeight => !IsNew && Parent is null ? FontWeights.SemiBold : FontWeights.Medium; public bool HasSubFolders => SubFolders is object && SubFolders.Count > 0; - public string Displayname - { - get - { - if (TotalPromptCount > 0) - { - return $"{Title} ({TotalPromptCount})"; - } + //public string Displayname + //{ + // get + // { + // if (TotalPromptCount > 0) + // { + // return $"{Title} ({TotalPromptCount})"; + // } - return Title; - } - } + // return Title; + // } + //} public int TotalPromptCount { @@ -183,6 +239,21 @@ namespace BeWo.ViewModel } } + public int TotalRoutineCount + { + get + { + var total = SubRoutines.Count; + + foreach (var folder in SubFolders.VMList) + { + total += folder.TotalRoutineCount; + } + + return total; + } + } + protected override void InitByDataContract(AiPromptbausteinFolderDC pDataContract) { _Title = pDataContract.Title; @@ -193,8 +264,9 @@ namespace BeWo.ViewModel _Position = pDataContract.Position; _IsExpanded = pDataContract.IsExpanded; _ActionType = pDataContract.ActionType; - _SubFolders = new AiPromptbausteinFolderListVM(pDataContract.SubFolders, this); + SubFolders = new AiPromptbausteinFolderListVM(pDataContract.SubFolders, this); SubPrompts = new AiPromptbausteinPromptListVM(pDataContract.SubPrompts); + SubRoutines = new AiPromptbausteinRoutineListVM(pDataContract.SubRoutines); } protected override AiPromptbausteinFolderDC MapToDataContract(AiPromptbausteinFolderDC pDataContract, bool doCommit) @@ -208,6 +280,7 @@ namespace BeWo.ViewModel pDataContract.ActionType = _ActionType; pDataContract.SubFolders = _SubFolders.CopyToDCList(doCommit); pDataContract.SubPrompts = _SubPrompts.CopyToDCList(doCommit); + pDataContract.SubRoutines = _SubRoutines.CopyToDCList(doCommit); return pDataContract; } diff --git a/BeWo/ViewModel/AiPromptbausteinRoutineVM.cs b/BeWo/ViewModel/AiPromptbausteinRoutineVM.cs index a80cf0aa0..fe8bf9f83 100644 --- a/BeWo/ViewModel/AiPromptbausteinRoutineVM.cs +++ b/BeWo/ViewModel/AiPromptbausteinRoutineVM.cs @@ -4,6 +4,7 @@ using BS.Shared; using BS.Shared.DataContracts; using BS.Shared.DataContracts.Compact; using BS.Shared.DataContracts.Feature.AI; +using BS.Shared.Extensions; namespace BeWo.ViewModel { @@ -85,6 +86,13 @@ namespace BeWo.ViewModel set => SetProperty(ref _Steps, value, nameof(Steps)); } + public bool CanShareEdit + { + get => BeWoApp.HasLoggedOnUserRight(UserRightType.AiModulePromptbausteinShare); + } + + public override bool IsDirty => base.IsDirty || Steps.IsDirty; + protected override void InitByDataContract(AiPromptbausteinRoutineDC pDataContract) { _Title = pDataContract.Title; @@ -111,10 +119,22 @@ namespace BeWo.ViewModel pDataContract.IsFavorite = _IsFavorite; pDataContract.ActionType = _ActionType; pDataContract.CanEdit = _CanEdit; - - pDataContract.Steps = _Steps.CopyToDCList(doCommit); + pDataContract.Steps = _Steps.CopyToDCList(true); return pDataContract; } + + public override void UpdateByDataContract(AiPromptbausteinRoutineDC pDataContract) + { + Title = pDataContract.Title; + Description = pDataContract.Description; + IsPublic = pDataContract.IsPublic; + IsFavorite = pDataContract.IsFavorite; + + var steps = new AiPromptbausteinRoutineStepListVM(pDataContract.Steps); + + Steps.VMList.Clear(); + Steps.VMList.AddRange(steps.VMList); + } } } diff --git a/BeWo/ViewModel/View/AI/AiPromptbausteinComplexSelectionViewModel.cs b/BeWo/ViewModel/View/AI/AiPromptbausteinComplexSelectionViewModel.cs index 2bb8b9fcd..ebbb46b48 100644 --- a/BeWo/ViewModel/View/AI/AiPromptbausteinComplexSelectionViewModel.cs +++ b/BeWo/ViewModel/View/AI/AiPromptbausteinComplexSelectionViewModel.cs @@ -58,6 +58,9 @@ namespace BeWo.ViewModel.View.AI public bool HasCopiedPrompt => CopiedPrompt is object; public CompactEmployeeDC CurrentEmployee => BeWoApp.CompactLoggedOnEmployee; + public bool CanOpenContextMenu { get; set; } + public string AcceptButtonText => CanOpenContextMenu ? "Absenden" : "Hinzufügen"; + public AiPromptbausteinSelectionComplexViewModel() { SendCommand = new DelegateCommand(Send, CanSend, true); @@ -73,11 +76,12 @@ namespace BeWo.ViewModel.View.AI WindowService = BeWoApp.MainControl.WindowService; InitCommands(); } - public AiPromptbausteinSelectionComplexViewModel(AiActionType aiActionType, AiPromptbausteinFolderListVM viewModel, bool isFavorite = false) : this(aiActionType) + public AiPromptbausteinSelectionComplexViewModel(AiActionType aiActionType, AiPromptbausteinFolderListVM viewModel, bool isFavorite = false, bool canOpen = true) : this(aiActionType) { LoadedActionType = aiActionType; Folders = viewModel; IsFavorite = isFavorite; + CanOpenContextMenu = canOpen; } private void InitCommands() @@ -387,7 +391,27 @@ namespace BeWo.ViewModel.View.AI void OpenAddRoutineDialog() { - + //var sel_folder = SelectedFolder; + //var new_vm = sel_folder.SubRoutines.CreateNewVM(); + + //new_vm.Creator = CurrentEmployee; + //new_vm.ParentFolderOid = sel_folder.DataContract.Oid; + //new_vm.CanEdit = true; + //new_vm.ActionType = AiActionType; + + //var vm = new AiPromptbausteinRoutineViewModel(new_vm, Folders, true); + + //vm.Accept_Button_Clicked += (s, e) => + //{ + // var new_dc = new_vm.CommitToDataContract(); + + // ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.InsertAiPromptbausteinPrompt(new List { new_dc }), + // (new_dcs) => ReloadVMList()); + //}; + + //Close(); + + //WindowService.Show(vm); } void OpenEditRoutineDialog() { diff --git a/BeWo/ViewModel/View/Administration/AiPromptbausteinComplexTreeViewModel.cs b/BeWo/ViewModel/View/Administration/AiPromptbausteinComplexTreeViewModel.cs index 6d2dfe728..326ea6ec7 100644 --- a/BeWo/ViewModel/View/Administration/AiPromptbausteinComplexTreeViewModel.cs +++ b/BeWo/ViewModel/View/Administration/AiPromptbausteinComplexTreeViewModel.cs @@ -21,6 +21,7 @@ namespace BeWo.ViewModel.View.Administration public class AiPromptbausteinComplexTreeViewModel : WindowViewModel { private AiPromptbausteinFolderVM _SelectedFolder; + private AbstractBaseVM _SelectedItem; private IBeWoWindowService WindowService { get; set; } private AiActionType AiActionType { get; set; } @@ -28,7 +29,6 @@ namespace BeWo.ViewModel.View.Administration public AiPromptbausteinFolderListVM Folders { get; set; } public AiPromptbausteinFolderVM Favoriten { get; set; } - public AiPromptbausteinPromptVM SelectedPrompt { get; set; } public AiPromptbausteinFolderVM CopiedFolder { get; set; } public AiPromptbausteinPromptVM CopiedPrompt { get; set; } @@ -45,6 +45,11 @@ namespace BeWo.ViewModel.View.Administration public DelegateCommand DeletePromptCommand { get; private set; } public DelegateCommand ChangeFavoritenStatePromptCommand { get; private set; } + public DelegateCommand OpenAddRoutineDialogCommand { get; private set; } + public DelegateCommand OpenEditRoutineDialogCommand { get; private set; } + public DelegateCommand DeleteRoutineCommand { get; private set; } + public DelegateCommand ChangeFavoritenStateRoutineCommand { get; private set; } + public bool CanEditPromptbausteine { get; set; } public AiPromptbausteinFolderVM SelectedFolder @@ -52,13 +57,19 @@ namespace BeWo.ViewModel.View.Administration get => _SelectedFolder; set => SetProperty(ref _SelectedFolder, value, nameof(SelectedFolder)); } - + + public AbstractBaseVM SelectedItem + { + get => _SelectedItem; + set => SetProperty(ref _SelectedItem, value, nameof(SelectedItem)); + } public AiPromptbausteinComplexTreeViewModel() : this(null, AiActionType.ServiceRecordConversation) { if (BeWoApp.IsInDesignMode) { - ReloadVMList(); + //ReloadVMList(); + InitDesigner(); SelectedFolder = Folders.VMList.FirstOrDefault(); return; } @@ -81,6 +92,11 @@ namespace BeWo.ViewModel.View.Administration DeletePromptCommand = new DelegateCommand(OpenDeletePromptDialog, canOpenDeletePromptDialog, false); ChangeFavoritenStatePromptCommand = new DelegateCommand(ChangeFavoritenStatePrompt, canChangeFavoritenStatePrompt, false); + OpenAddRoutineDialogCommand = new DelegateCommand(OpenAddRoutineDialog, canOpenAddRoutineDialog, false); + OpenEditRoutineDialogCommand = new DelegateCommand(OpenEditRoutineDialog, canOpenEditRoutineDialog, false); + DeleteRoutineCommand = new DelegateCommand(OpenDeleteRoutineDialog, canOpenDeleteRoutineDialog, false); + ChangeFavoritenStateRoutineCommand = new DelegateCommand(ChangeFavoritenStateRoutine, canChangeFavoritenStateRoutine, false); + CanEditPromptbausteine = BeWoApp.HasLoggedOnUserRight(UserRightType.AiModulePromptbausteineEdit); } @@ -111,6 +127,10 @@ namespace BeWo.ViewModel.View.Administration PastePromptCommand.RaiseCanExecuteChanged(); DeletePromptCommand.RaiseCanExecuteChanged(); ChangeFavoritenStatePromptCommand.RaiseCanExecuteChanged(); + OpenAddRoutineDialogCommand.RaiseCanExecuteChanged(); + OpenEditRoutineDialogCommand.RaiseCanExecuteChanged(); + DeleteRoutineCommand.RaiseCanExecuteChanged(); + ChangeFavoritenStateRoutineCommand.RaiseCanExecuteChanged(); } public void SaveVMList() @@ -355,16 +375,20 @@ namespace BeWo.ViewModel.View.Administration vm.Accept_Button_Clicked += (s, e) => { sel_folder.SubPrompts.VMList.Add(new_vm); - SelectedPrompt = new_vm; + SelectedItem = new_vm; }; WindowService.Show(vm); } void OpenEditPromptDialog() { - var sel_prompt = SelectedPrompt; + var sel_prompt = SelectedItem as AiPromptbausteinPromptVM; + + if (SelectedItem is null) + throw new Exception("invalid operation"); + var sel_dc = sel_prompt.CopyToEmptyDataContract(); - sel_dc.CanEdit = SelectedPrompt.CanEdit; + sel_dc.CanEdit = sel_prompt.CanEdit; var edit_vm = new AiPromptbausteinPromptVM(sel_dc); var vm = new AiPromptbausteinPromptViewModel(edit_vm, false); @@ -383,7 +407,7 @@ namespace BeWo.ViewModel.View.Administration private void UpdateSelectedPromptFavorite(AiPromptbausteinPromptVM sel_prompt = null) { if (sel_prompt is null) - sel_prompt = SelectedPrompt; + sel_prompt = SelectedItem as AiPromptbausteinPromptVM; if (sel_prompt.IsFavorite && !Favoriten.SubPrompts.VMList.Contains(sel_prompt)) Favoriten.SubPrompts.VMList.Add(sel_prompt); @@ -391,7 +415,27 @@ namespace BeWo.ViewModel.View.Administration { Favoriten.SubPrompts.VMList.Remove(sel_prompt); - if (Favoriten.SubPrompts.Count == 0) + if (Favoriten.SubRoutines.Count == 0 && Favoriten.SubPrompts.Count == 0) + { + var selected_folder = SelectedFolder; + SelectedFolder = null; + SelectedFolder = selected_folder; + } + } + } + + private void UpdateSelectedRoutineFavorite(AiPromptbausteinRoutineVM sel_routine = null) + { + if (sel_routine is null) + sel_routine = SelectedItem as AiPromptbausteinRoutineVM; + + if (sel_routine.IsFavorite && !Favoriten.SubRoutines.VMList.Contains(sel_routine)) + Favoriten.SubRoutines.VMList.Add(sel_routine); + else if (!sel_routine.IsFavorite && Favoriten.SubRoutines.VMList.Contains(sel_routine)) + { + Favoriten.SubRoutines.VMList.Remove(sel_routine); + + if (Favoriten.SubRoutines.Count == 0 && Favoriten.SubPrompts.Count == 0) { var selected_folder = SelectedFolder; SelectedFolder = null; @@ -402,7 +446,7 @@ namespace BeWo.ViewModel.View.Administration void CopyPrompt() { - CopiedPrompt = SelectedPrompt; + CopiedPrompt = SelectedItem as AiPromptbausteinPromptVM; } void PastePrompt() { @@ -421,7 +465,7 @@ namespace BeWo.ViewModel.View.Administration } void OpenDeletePromptDialog() { - var sel_prompt = SelectedPrompt; + var sel_prompt = SelectedItem as AiPromptbausteinPromptVM; var folder = SelectedFolder; var txt = "Möchten Sie den ausgewählten Prompt wirklich löschen?"; @@ -430,12 +474,12 @@ namespace BeWo.ViewModel.View.Administration if (result != MessageBoxResult.OK) return; - folder.SubPrompts.VMList.Remove(SelectedPrompt); + folder.SubPrompts.VMList.Remove(sel_prompt); } void ChangeFavoritenStatePrompt() { - var sel_prompt = SelectedPrompt; + var sel_prompt = SelectedItem as AiPromptbausteinPromptVM; sel_prompt.IsFavorite = !sel_prompt.IsFavorite; @@ -448,11 +492,11 @@ namespace BeWo.ViewModel.View.Administration } bool canOpenEditPromptDialog() { - return SelectedPrompt is object; + return SelectedItem as AiPromptbausteinPromptVM is object; } bool canCopyPrompt() { - return CanEditPromptbausteine && SelectedPrompt is object; + return CanEditPromptbausteine && SelectedItem as AiPromptbausteinPromptVM is object; } bool canPastePrompt() { @@ -460,36 +504,93 @@ namespace BeWo.ViewModel.View.Administration } bool canOpenDeletePromptDialog() { - return CanEditPromptbausteine && (SelectedPrompt?.CanEdit ?? false); + return CanEditPromptbausteine && ((SelectedItem as AiPromptbausteinPromptVM)?.CanEdit ?? false); } bool canChangeFavoritenStatePrompt() { - return SelectedPrompt is object; + return SelectedItem as AiPromptbausteinPromptVM is object; } // --- Routine Commands void OpenAddRoutineDialog() { + var sel_folder = SelectedFolder; + var new_vm = sel_folder.SubRoutines.CreateNewVM(); + new_vm.Creator = CurrentEmployee; + new_vm.ParentFolderOid = sel_folder.DataContract.Oid; + new_vm.CanEdit = true; + new_vm.ActionType = AiActionType; + + var vm = new AiPromptbausteinRoutineViewModel(new_vm, Folders, true); + + vm.Accept_Button_Clicked += (s, e) => + { + sel_folder.SubRoutines.VMList.Add(new_vm); + SelectedItem = new_vm; + }; + + WindowService.Show(vm); } void OpenEditRoutineDialog() { + var sel_prompt = SelectedItem as AiPromptbausteinRoutineVM; + if (SelectedItem is null) + throw new Exception("invalid operation"); + + var sel_dc = sel_prompt.CopyToEmptyDataContract(); + sel_dc.CanEdit = sel_prompt.CanEdit; + var edit_vm = new AiPromptbausteinRoutineVM(sel_dc); + + var vm = new AiPromptbausteinRoutineViewModel(edit_vm, Folders, false); + + vm.Accept_Button_Clicked += (s, e) => + { + var edit_dc = edit_vm.CommitToDataContract(); + sel_prompt.UpdateByDataContract(edit_dc); + + UpdateSelectedRoutineFavorite(sel_prompt); + }; + + WindowService.Show(vm); } void OpenDeleteRoutineDialog() { + var sel_prompt = SelectedItem as AiPromptbausteinRoutineVM; + var folder = SelectedFolder; + var txt = "Möchten Sie die ausgewählte Routine wirklich löschen?"; + var result = MessageBox.Show(txt, "Hinweis", MessageBoxButton.OKCancel); + + if (result != MessageBoxResult.OK) + return; + + folder.SubRoutines.VMList.Remove(sel_prompt); } void ChangeFavoritenStateRoutine() { + var sel_routine = SelectedItem as AiPromptbausteinRoutineVM; + sel_routine.IsFavorite = !sel_routine.IsFavorite; + + UpdateSelectedRoutineFavorite(sel_routine); } - //bool canOpenAddRoutineDialog() => CanEditPromptbausteine && (SelectedFolder?.CanAddPrompt ?? false); - //bool canOpenEditRoutineDialog() => SelectedRoutine is object; - //bool canOpenDeleteRoutineDialog() => CanEditPromptbausteine && (SelectedRoutine?.CanEdit ?? false); - //bool canChangeFavoritenStateRoutine() => SelectedRoutine is object; + bool canOpenAddRoutineDialog() => CanEditPromptbausteine && (SelectedFolder?.CanAddPrompt ?? false); + bool canOpenEditRoutineDialog() => SelectedItem is AiPromptbausteinRoutineVM; + bool canOpenDeleteRoutineDialog() => CanEditPromptbausteine && ((SelectedItem as AiPromptbausteinRoutineVM)?.CanEdit ?? false); + bool canChangeFavoritenStateRoutine() => SelectedItem is AiPromptbausteinRoutineVM; + + void InitDesigner() + { + var root = PredefinedAiPromptbausteinFolders.CreateSubTree(AiActionType.ServiceRecordConversation); + + var root_vm = new AiPromptbausteinFolderListVM(root); + + Folders = root_vm; + } } } diff --git a/BeWo/ViewModel/View/Administration/AiPromptbausteinRoutineViewModel.cs b/BeWo/ViewModel/View/Administration/AiPromptbausteinRoutineViewModel.cs new file mode 100644 index 000000000..a08247cc7 --- /dev/null +++ b/BeWo/ViewModel/View/Administration/AiPromptbausteinRoutineViewModel.cs @@ -0,0 +1,49 @@ +using BeWo.ViewModel.ListViewModel; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BeWo.ViewModel.View.Administration +{ + public class AiPromptbausteinRoutineViewModel : AcceptCancelDialogViewModel + { + private readonly bool _IsNew; + public AiPromptbausteinRoutineStepVM _SelectedStep; + + public AiPromptbausteinRoutineViewModel(AiPromptbausteinRoutineVM viewModel, AiPromptbausteinFolderListVM folders, bool isNew) : base() + { + ViewModel = viewModel; + FolderListVM = folders; + _IsNew = isNew; + + ViewModel.PropertyChanged += (s, e) => + { + AcceptCommand.RaiseCanExecuteChanged(); + }; + + ViewModel.Steps.VMList.ListChanged += (s, e) => + { + AcceptCommand.RaiseCanExecuteChanged(); + }; + } + + + public AiPromptbausteinFolderListVM FolderListVM { get; set; } + public AiPromptbausteinRoutineVM ViewModel { get; private set; } + + public AiPromptbausteinRoutineStepVM SelectedStep + { + get => _SelectedStep; + set => SetProperty(ref _SelectedStep, value, nameof(SelectedStep)); + } + + public string AcceptButtonText => _IsNew ? "Hinzufügen" : "Speichern"; + + protected override bool canAccept() + { + return (_IsNew || ViewModel.IsDirty) && !string.IsNullOrWhiteSpace(ViewModel.Title) && (ViewModel.Steps?.VMList.Any() ?? false); + } + } +} diff --git a/Service/Plugins/AiPromptbausteineService.cs b/Service/Plugins/AiPromptbausteineService.cs index caea7cbb4..66fc0866f 100644 --- a/Service/Plugins/AiPromptbausteineService.cs +++ b/Service/Plugins/AiPromptbausteineService.cs @@ -41,7 +41,6 @@ namespace BeWo.Service.Plugins return result; } - public IEnumerable InsertAiPromptbausteinFolder(IEnumerable folders) { var entities = MapperFactory.AiPromptbausteinFolder.MapToNewEntities(folders); @@ -50,7 +49,6 @@ namespace BeWo.Service.Plugins return null; } - public IEnumerable InsertAiPromptbausteinPrompt(IEnumerable prompts) { var entities = MapperFactory.AiPromptbausteinPrompt.MapToNewEntities(prompts); @@ -59,7 +57,14 @@ namespace BeWo.Service.Plugins return null; } + public IEnumerable InsertAiPromptbausteinRoutine(IEnumerable routine) + { + var entities = MapperFactory.AiPromptbausteinRoutine.MapToNewEntities(routine); + DAOFactory.GenericDAO.Insert(entities); + + return null; + } public IEnumerable UpdateAiPromptbausteinFolder(IEnumerable folders) { var originale = DAOFactory.GenericDAO.LoadByIDs(folders.Select(sc => sc.Oid.Value)); @@ -70,7 +75,6 @@ namespace BeWo.Service.Plugins return null; } - public IEnumerable UpdateAiPromptbausteinPrompt(IEnumerable prompts) { var originale = DAOFactory.GenericDAO.LoadByIDs(prompts.Select(sc => sc.Oid.Value)); @@ -81,6 +85,16 @@ namespace BeWo.Service.Plugins return null; } + public IEnumerable UpdateAiPromptbausteinRoutine(IEnumerable routine) + { + var originale = DAOFactory.GenericDAO.LoadByIDs(routine.Select(sc => sc.Oid.Value)); + var routine2 = routine.ToList(); + MapperFactory.AiPromptbausteinRoutine.MergeWithEntitys(routine2, originale); + + DAOFactory.GenericDAO.Update(originale); + + return null; + } public void DeleteAiPromptbausteinFolder(Dictionary oid2version) { @@ -107,6 +121,13 @@ namespace BeWo.Service.Plugins DAOFactory.GenericDAO.SetActivationType(originale, BS.Shared.ActivationTypeId.Deleted); } + public void DeleteAiPromptbausteinRoutine(Dictionary oid2version) + { + var originale = DAOFactory.GenericDAO.LoadByIDs(oid2version.Select(e => e.Key)); + originale.DoForEach(or => MapperFactory.AiPromptbausteinRoutine.ConcurrencyCheck(oid2version[or.Oid.Value], or)); + + DAOFactory.GenericDAO.SetActivationType(originale, BS.Shared.ActivationTypeId.Deleted); + } private AiPromptbausteinFolderDC getOwnFolder(AiActionType aiActionType) { @@ -134,6 +155,39 @@ namespace BeWo.Service.Plugins own_bib.SubPrompts.AddRange(own_prompts_dcs); + + + var example_routine = new AiPromptbausteinRoutineDC(); + example_routine.ActionType = aiActionType; + example_routine.CanEdit = true; + example_routine.IsPublic = true; + example_routine.Description = "Beschreibung"; + example_routine.Oid = 1000; + example_routine.ParentFolderOid = own_bib.Oid; + example_routine.Title = "Routine Title"; + example_routine.Steps = new List(); + + if (own_prompts_dcs.Count > 0) + example_routine.Steps.Add(new AiPromptbausteinRoutineStepDC() + { + Oid = 1001, + Position = 0, + PromptReference = own_prompts_dcs?[0], + }); + + if (own_bib.SubFolders.Count > 0 && own_bib.SubFolders[0].SubPrompts.Count > 0) + example_routine.Steps.Add(new AiPromptbausteinRoutineStepDC() + { + Oid = 1001, + Position = 0, + PromptReference = own_bib.SubFolders[0].SubPrompts[0], + }); + + if (own_prompts_dcs.Count > 0) + { + own_bib.SubRoutines = new List { example_routine }; + } + return own_bib; } private void initOwnFolder(AiPromptbausteinFolderDC folder) diff --git a/Service/ServiceContracts/Enhanced/IAiEnhancedService.cs b/Service/ServiceContracts/Enhanced/IAiEnhancedService.cs index d39bfb75a..87ff5b096 100644 --- a/Service/ServiceContracts/Enhanced/IAiEnhancedService.cs +++ b/Service/ServiceContracts/Enhanced/IAiEnhancedService.cs @@ -86,6 +86,11 @@ namespace BeWo.Service.ServiceContracts.Enhanced [OperationContract] [RequireWcfAuthorization(UserRightType.AiModulePromptbausteineEdit)] IEnumerable InsertAiPromptbausteinPrompt(IEnumerable prompts); + + [FaultContract(typeof(BeWoFault))] + [OperationContract] + [RequireWcfAuthorization(UserRightType.AiModulePromptbausteineEdit)] + IEnumerable InsertAiPromptbausteinRoutine(IEnumerable routine); [FaultContract(typeof(BeWoFault))] [OperationContract] @@ -94,8 +99,13 @@ namespace BeWo.Service.ServiceContracts.Enhanced [FaultContract(typeof(BeWoFault))] [OperationContract] - [RequireWcfAuthorization(UserRightType.AiModulePromptbausteineView)] + [RequireWcfAuthorization(UserRightType.AiModulePromptbausteineEdit)] IEnumerable UpdateAiPromptbausteinPrompt(IEnumerable prompts); + + [FaultContract(typeof(BeWoFault))] + [OperationContract] + [RequireWcfAuthorization(UserRightType.AiModulePromptbausteineEdit)] + IEnumerable UpdateAiPromptbausteinRoutine(IEnumerable routine); [FaultContract(typeof(BeWoFault))] [OperationContract] @@ -106,6 +116,11 @@ namespace BeWo.Service.ServiceContracts.Enhanced [OperationContract] [RequireWcfAuthorization(UserRightType.AiModulePromptbausteineEdit)] void DeleteAiPromptbausteinPrompt(Dictionary oid2version); + + [FaultContract(typeof(BeWoFault))] + [OperationContract] + [RequireWcfAuthorization(UserRightType.AiModulePromptbausteineEdit)] + void DeleteAiPromptbausteinRoutine(Dictionary oid2version); [FaultContract(typeof(BeWoFault))] [OperationContract] diff --git a/Service/ServiceImplementations/Enhanced/AiEnhancedServiceImp.cs b/Service/ServiceImplementations/Enhanced/AiEnhancedServiceImp.cs index 490a56888..312ac7221 100644 --- a/Service/ServiceImplementations/Enhanced/AiEnhancedServiceImp.cs +++ b/Service/ServiceImplementations/Enhanced/AiEnhancedServiceImp.cs @@ -71,18 +71,27 @@ namespace BeWo.Service.ServiceImplementations.Enhanced public IEnumerable InsertAiPromptbausteinPrompt(IEnumerable prompts) => GetAiPromptbausteineService().InsertAiPromptbausteinPrompt(prompts); + + public IEnumerable InsertAiPromptbausteinRoutine(IEnumerable routine) + => GetAiPromptbausteineService().InsertAiPromptbausteinRoutine(routine); public IEnumerable UpdateAiPromptbausteinFolder(IEnumerable folders) => GetAiPromptbausteineService().UpdateAiPromptbausteinFolder(folders); public IEnumerable UpdateAiPromptbausteinPrompt(IEnumerable prompts) => GetAiPromptbausteineService().UpdateAiPromptbausteinPrompt(prompts); + + public IEnumerable UpdateAiPromptbausteinRoutine(IEnumerable routine) + => GetAiPromptbausteineService().UpdateAiPromptbausteinRoutine(routine); public void DeleteAiPromptbausteinFolder(Dictionary oid2version) => GetAiPromptbausteineService().DeleteAiPromptbausteinFolder(oid2version); public void DeleteAiPromptbausteinPrompt(Dictionary oid2version) => GetAiPromptbausteineService().DeleteAiPromptbausteinPrompt(oid2version); + + public void DeleteAiPromptbausteinRoutine(Dictionary oid2version) + => GetAiPromptbausteineService().DeleteAiPromptbausteinRoutine(oid2version); private AiPromptbausteineService GetAiPromptbausteineService() { diff --git a/Shared/DataContracts/Feature/AI/AiPromptbausteinFolderDC.cs b/Shared/DataContracts/Feature/AI/AiPromptbausteinFolderDC.cs index fb7b66e29..0e1d2c169 100644 --- a/Shared/DataContracts/Feature/AI/AiPromptbausteinFolderDC.cs +++ b/Shared/DataContracts/Feature/AI/AiPromptbausteinFolderDC.cs @@ -19,9 +19,11 @@ namespace BS.Shared.DataContracts.Feature.AI [DataMember] public AiActionType ActionType { get; set; } [DataMember] public List SubFolders { get; set; } [DataMember] public List SubPrompts { get; set; } + [DataMember] public List SubRoutines { get; set; } [DataMember] public bool CanAddFolder { get; set; } [DataMember] public bool CanAddPrompt { get; set; } + [DataMember] public bool CanAddRoutine { get; set; } [DataMember] public bool CanEdit { get; set; } [DataMember] public bool IsNewFeature { get; set; } } From bd960f1c6c53b1f33bb10c079dd04bd9c1215f11 Mon Sep 17 00:00:00 2001 From: Rene Evertz Date: Thu, 7 May 2026 15:50:21 +0200 Subject: [PATCH 02/70] Steps werden geupdatet beim Speichern --- BeWo/Services/BeWoWindowService.cs | 2 +- .../AiPromptbausteinRoutineStepVM.cs | 7 ++++ BeWo/ViewModel/AiPromptbausteinRoutineVM.cs | 5 +-- .../ListViewModel/AbstractDCListMapperVM.cs | 7 +++- .../AiPromptbausteinRoutineStepListVM.cs | 37 +++++++++++++++++++ 5 files changed, 52 insertions(+), 6 deletions(-) diff --git a/BeWo/Services/BeWoWindowService.cs b/BeWo/Services/BeWoWindowService.cs index b2070620c..fee6d373d 100644 --- a/BeWo/Services/BeWoWindowService.cs +++ b/BeWo/Services/BeWoWindowService.cs @@ -117,7 +117,7 @@ namespace BeWo.Services Height = 400, Width = 600 }; - Show("KI Promptbaustein Prompt", control, viewModel, options); + Show("KI Promptbaustein Routine", control, viewModel, options); } public void ShowAiPromptbausteinActionResultWindow(AiPromptbausteinActionResultViewModel viewModel) { diff --git a/BeWo/ViewModel/AiPromptbausteinRoutineStepVM.cs b/BeWo/ViewModel/AiPromptbausteinRoutineStepVM.cs index 9fb51bcb9..4cf4660bf 100644 --- a/BeWo/ViewModel/AiPromptbausteinRoutineStepVM.cs +++ b/BeWo/ViewModel/AiPromptbausteinRoutineStepVM.cs @@ -50,5 +50,12 @@ namespace BeWo.ViewModel return pDataContract; } + + public override void UpdateByDataContract(AiPromptbausteinRoutineStepDC pDataContract) + { + Position = pDataContract.Position; + PromptReference = pDataContract.PromptReference; + ReferenceVersion = pDataContract.ReferenceVersion; + } } } diff --git a/BeWo/ViewModel/AiPromptbausteinRoutineVM.cs b/BeWo/ViewModel/AiPromptbausteinRoutineVM.cs index fe8bf9f83..bc7c5324a 100644 --- a/BeWo/ViewModel/AiPromptbausteinRoutineVM.cs +++ b/BeWo/ViewModel/AiPromptbausteinRoutineVM.cs @@ -131,10 +131,7 @@ namespace BeWo.ViewModel IsPublic = pDataContract.IsPublic; IsFavorite = pDataContract.IsFavorite; - var steps = new AiPromptbausteinRoutineStepListVM(pDataContract.Steps); - - Steps.VMList.Clear(); - Steps.VMList.AddRange(steps.VMList); + Steps.UpdateByDataContracts(pDataContract.Steps); } } } diff --git a/BeWo/ViewModel/ListViewModel/AbstractDCListMapperVM.cs b/BeWo/ViewModel/ListViewModel/AbstractDCListMapperVM.cs index 41b8e3513..63cd9954d 100644 --- a/BeWo/ViewModel/ListViewModel/AbstractDCListMapperVM.cs +++ b/BeWo/ViewModel/ListViewModel/AbstractDCListMapperVM.cs @@ -291,5 +291,10 @@ namespace BeWo.ViewModel.ListViewModel { return null; } - } + + public virtual void UpdateByDataContracts(List pDataContracts) + { + throw new NotImplementedException(); + } + } } \ No newline at end of file diff --git a/BeWo/ViewModel/ListViewModel/AiPromptbausteinRoutineStepListVM.cs b/BeWo/ViewModel/ListViewModel/AiPromptbausteinRoutineStepListVM.cs index dbb66b835..d1649157f 100644 --- a/BeWo/ViewModel/ListViewModel/AiPromptbausteinRoutineStepListVM.cs +++ b/BeWo/ViewModel/ListViewModel/AiPromptbausteinRoutineStepListVM.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using BS.Shared.DataContracts.Feature.AI; +using BS.Shared.Extensions; namespace BeWo.ViewModel.ListViewModel { @@ -13,5 +14,41 @@ namespace BeWo.ViewModel.ListViewModel { } + + public override void UpdateByDataContracts(List pDataContracts) + { + var count_a = Count; + var count_b = pDataContracts.Count; + + // 1-k updaten + var count_toupdate = Math.Min(count_a, count_b); + for ( var i = 0; i < count_toupdate; i++) + { + var a = VMList[i]; + var b = pDataContracts[i]; + + a.UpdateByDataContract(b); + } + + if (count_a == count_b) + return; + + if(count_a > count_b) + { + for (var i = count_a - 1; i > count_toupdate - 1; i--) + { + VMList.RemoveAt(i); + } + } + else + { + for (int i = count_toupdate; i < count_b; i++) + { + var dc = pDataContracts[i]; + var vm = new AiPromptbausteinRoutineStepVM(dc); + VMList.Add(vm); + } + } + } } } \ No newline at end of file From fe3588f1bae226164f241c105d9d7105615352b9 Mon Sep 17 00:00:00 2001 From: Rene Evertz Date: Tue, 12 May 2026 11:47:04 +0200 Subject: [PATCH 03/70] =?UTF-8?q?Generic=20Business=20Logic=20+=20Oberfl?= =?UTF-8?q?=C3=A4che?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GeneratedAiEnhancedService.cs | 42 +-- .../AI/AiPromptbausteinComplexTreeView.xaml | 197 +++++++------ .../AiPromptbausteinComplexTreeView.xaml.cs | 7 +- BeWo/ViewModel/AiPromptbausteinFolderVM.cs | 21 +- BeWo/ViewModel/AiPromptbausteinPromptVM.cs | 6 +- .../AiPromptbausteinRoutineStepVM.cs | 2 + BeWo/ViewModel/AiPromptbausteinRoutineVM.cs | 4 + .../AiPromptbausteinRoutineStepListVM.cs | 2 + BeWo/ViewModel/VMFactory.cs | 6 + .../View/AI/AiConversationChatViewModel.cs | 2 +- ...PromptbausteinComplexSelectionViewModel.cs | 24 +- .../AiPromptbausteinComplexTreeViewModel.cs | 271 ++++++++---------- .../AiPromptbausteinPromptViewModel.cs | 2 +- Data/Data.csproj | 2 + Data/Entities/AiPromptbausteinFolder.cs | 2 + Data/Entities/AiPromptbausteinRoutine.cs | 6 +- Data/Mappings/AiPromptbausteinFolder.hbm.xml | 5 + Data/Mappings/AiPromptbausteinRoutine.hbm.xml | 34 +++ .../AiPromptbausteinRoutineStep.hbm.xml | 22 ++ Host/Web.Deploy.config | 3 +- ...5-12 AiPromptbausteinRoutine Favoriten.txt | 27 ++ .../AiPromptbausteinFolderLogic.cs | 69 +++++ .../AiPromptbausteinPromptLogic.cs | 38 +++ .../AiPromptbausteinRoutineLogic.cs | 16 ++ Service/BusinessLogic/GenericBusinessLogic.cs | 64 +++++ ...bausteinFolderDC_AiPromptbausteinFolder.cs | 4 + ...usteinRoutineDC_AiPromptbausteinRoutine.cs | 23 +- Service/Plugins/AiPromptbausteineService.cs | 5 + Service/Service.csproj | 4 + .../Enhanced/IAiEnhancedService.cs | 36 +-- .../Enhanced/AiEnhancedServiceImp.cs | 62 ++-- 31 files changed, 675 insertions(+), 333 deletions(-) create mode 100644 Data/Mappings/AiPromptbausteinRoutine.hbm.xml create mode 100644 Data/Mappings/AiPromptbausteinRoutineStep.hbm.xml create mode 100644 Model/Changes_2026-05-12 AiPromptbausteinRoutine Favoriten.txt create mode 100644 Service/BusinessLogic/AiPromptbausteinFolderLogic.cs create mode 100644 Service/BusinessLogic/AiPromptbausteinPromptLogic.cs create mode 100644 Service/BusinessLogic/AiPromptbausteinRoutineLogic.cs create mode 100644 Service/BusinessLogic/GenericBusinessLogic.cs diff --git a/BeWo/ServiceProxy/GeneratedAiEnhancedService.cs b/BeWo/ServiceProxy/GeneratedAiEnhancedService.cs index c17dfc380..8dc820890 100644 --- a/BeWo/ServiceProxy/GeneratedAiEnhancedService.cs +++ b/BeWo/ServiceProxy/GeneratedAiEnhancedService.cs @@ -69,42 +69,42 @@ namespace BeWo.ServiceProxy [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IAiEnhancedService/InsertAiPromptbausteinFolder", ReplyAction="http://tempuri.org/IAiEnhancedService/InsertAiPromptbausteinFolderResponse")] [System.ServiceModel.FaultContractAttribute(typeof(BS.Shared.Core.BeWoFault), Action="http://tempuri.org/IAiEnhancedService/InsertAiPromptbausteinFolderBeWoFaultFault", Name="BeWoFault", Namespace="http://schemas.datacontract.org/2004/07/BS.Shared.Core")] - System.Collections.Generic.List InsertAiPromptbausteinFolder(System.Collections.Generic.List folders); + BS.Shared.DataContracts.Feature.AI.AiPromptbausteinFolderDC InsertAiPromptbausteinFolder(BS.Shared.DataContracts.Feature.AI.AiPromptbausteinFolderDC folders); [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IAiEnhancedService/InsertAiPromptbausteinPrompt", ReplyAction="http://tempuri.org/IAiEnhancedService/InsertAiPromptbausteinPromptResponse")] [System.ServiceModel.FaultContractAttribute(typeof(BS.Shared.Core.BeWoFault), Action="http://tempuri.org/IAiEnhancedService/InsertAiPromptbausteinPromptBeWoFaultFault", Name="BeWoFault", Namespace="http://schemas.datacontract.org/2004/07/BS.Shared.Core")] - System.Collections.Generic.List InsertAiPromptbausteinPrompt(System.Collections.Generic.List prompts); + BS.Shared.DataContracts.Feature.AI.AiPromptbausteinPromptDC InsertAiPromptbausteinPrompt(BS.Shared.DataContracts.Feature.AI.AiPromptbausteinPromptDC prompts); [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IAiEnhancedService/InsertAiPromptbausteinRoutine", ReplyAction="http://tempuri.org/IAiEnhancedService/InsertAiPromptbausteinRoutineResponse")] [System.ServiceModel.FaultContractAttribute(typeof(BS.Shared.Core.BeWoFault), Action="http://tempuri.org/IAiEnhancedService/InsertAiPromptbausteinRoutineBeWoFaultFault" + "", Name="BeWoFault", Namespace="http://schemas.datacontract.org/2004/07/BS.Shared.Core")] - System.Collections.Generic.List InsertAiPromptbausteinRoutine(System.Collections.Generic.List routine); + BS.Shared.DataContracts.Feature.AI.AiPromptbausteinRoutineDC InsertAiPromptbausteinRoutine(BS.Shared.DataContracts.Feature.AI.AiPromptbausteinRoutineDC routine); [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IAiEnhancedService/UpdateAiPromptbausteinFolder", ReplyAction="http://tempuri.org/IAiEnhancedService/UpdateAiPromptbausteinFolderResponse")] [System.ServiceModel.FaultContractAttribute(typeof(BS.Shared.Core.BeWoFault), Action="http://tempuri.org/IAiEnhancedService/UpdateAiPromptbausteinFolderBeWoFaultFault", Name="BeWoFault", Namespace="http://schemas.datacontract.org/2004/07/BS.Shared.Core")] - System.Collections.Generic.List UpdateAiPromptbausteinFolder(System.Collections.Generic.List folders); + BS.Shared.DataContracts.Feature.AI.AiPromptbausteinFolderDC UpdateAiPromptbausteinFolder(BS.Shared.DataContracts.Feature.AI.AiPromptbausteinFolderDC folders); [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IAiEnhancedService/UpdateAiPromptbausteinPrompt", ReplyAction="http://tempuri.org/IAiEnhancedService/UpdateAiPromptbausteinPromptResponse")] [System.ServiceModel.FaultContractAttribute(typeof(BS.Shared.Core.BeWoFault), Action="http://tempuri.org/IAiEnhancedService/UpdateAiPromptbausteinPromptBeWoFaultFault", Name="BeWoFault", Namespace="http://schemas.datacontract.org/2004/07/BS.Shared.Core")] - System.Collections.Generic.List UpdateAiPromptbausteinPrompt(System.Collections.Generic.List prompts); + BS.Shared.DataContracts.Feature.AI.AiPromptbausteinPromptDC UpdateAiPromptbausteinPrompt(BS.Shared.DataContracts.Feature.AI.AiPromptbausteinPromptDC prompts); [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IAiEnhancedService/UpdateAiPromptbausteinRoutine", ReplyAction="http://tempuri.org/IAiEnhancedService/UpdateAiPromptbausteinRoutineResponse")] [System.ServiceModel.FaultContractAttribute(typeof(BS.Shared.Core.BeWoFault), Action="http://tempuri.org/IAiEnhancedService/UpdateAiPromptbausteinRoutineBeWoFaultFault" + "", Name="BeWoFault", Namespace="http://schemas.datacontract.org/2004/07/BS.Shared.Core")] - System.Collections.Generic.List UpdateAiPromptbausteinRoutine(System.Collections.Generic.List routine); + BS.Shared.DataContracts.Feature.AI.AiPromptbausteinRoutineDC UpdateAiPromptbausteinRoutine(BS.Shared.DataContracts.Feature.AI.AiPromptbausteinRoutineDC routine); [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IAiEnhancedService/DeleteAiPromptbausteinFolder", ReplyAction="http://tempuri.org/IAiEnhancedService/DeleteAiPromptbausteinFolderResponse")] [System.ServiceModel.FaultContractAttribute(typeof(BS.Shared.Core.BeWoFault), Action="http://tempuri.org/IAiEnhancedService/DeleteAiPromptbausteinFolderBeWoFaultFault", Name="BeWoFault", Namespace="http://schemas.datacontract.org/2004/07/BS.Shared.Core")] - void DeleteAiPromptbausteinFolder(System.Collections.Generic.Dictionary oid2version); + void DeleteAiPromptbausteinFolder(BS.Shared.DataContracts.Feature.AI.AiPromptbausteinFolderDC folder); [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IAiEnhancedService/DeleteAiPromptbausteinPrompt", ReplyAction="http://tempuri.org/IAiEnhancedService/DeleteAiPromptbausteinPromptResponse")] [System.ServiceModel.FaultContractAttribute(typeof(BS.Shared.Core.BeWoFault), Action="http://tempuri.org/IAiEnhancedService/DeleteAiPromptbausteinPromptBeWoFaultFault", Name="BeWoFault", Namespace="http://schemas.datacontract.org/2004/07/BS.Shared.Core")] - void DeleteAiPromptbausteinPrompt(System.Collections.Generic.Dictionary oid2version); + void DeleteAiPromptbausteinPrompt(BS.Shared.DataContracts.Feature.AI.AiPromptbausteinPromptDC prompt); [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IAiEnhancedService/DeleteAiPromptbausteinRoutine", ReplyAction="http://tempuri.org/IAiEnhancedService/DeleteAiPromptbausteinRoutineResponse")] [System.ServiceModel.FaultContractAttribute(typeof(BS.Shared.Core.BeWoFault), Action="http://tempuri.org/IAiEnhancedService/DeleteAiPromptbausteinRoutineBeWoFaultFault" + "", Name="BeWoFault", Namespace="http://schemas.datacontract.org/2004/07/BS.Shared.Core")] - void DeleteAiPromptbausteinRoutine(System.Collections.Generic.Dictionary oid2version); + void DeleteAiPromptbausteinRoutine(BS.Shared.DataContracts.Feature.AI.AiPromptbausteinRoutineDC routine); [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IAiEnhancedService/ExecuteAiFunctionServiceRecordDocumentation" + "", ReplyAction="http://tempuri.org/IAiEnhancedService/ExecuteAiFunctionServiceRecordDocumentation" + @@ -216,49 +216,49 @@ namespace BeWo.ServiceProxy return base.Channel.GetAiPromptbausteinFolder(aiActionType); } - public System.Collections.Generic.List InsertAiPromptbausteinFolder(System.Collections.Generic.List folders) + public BS.Shared.DataContracts.Feature.AI.AiPromptbausteinFolderDC InsertAiPromptbausteinFolder(BS.Shared.DataContracts.Feature.AI.AiPromptbausteinFolderDC folders) { return base.Channel.InsertAiPromptbausteinFolder(folders); } - public System.Collections.Generic.List InsertAiPromptbausteinPrompt(System.Collections.Generic.List prompts) + public BS.Shared.DataContracts.Feature.AI.AiPromptbausteinPromptDC InsertAiPromptbausteinPrompt(BS.Shared.DataContracts.Feature.AI.AiPromptbausteinPromptDC prompts) { return base.Channel.InsertAiPromptbausteinPrompt(prompts); } - public System.Collections.Generic.List InsertAiPromptbausteinRoutine(System.Collections.Generic.List routine) + public BS.Shared.DataContracts.Feature.AI.AiPromptbausteinRoutineDC InsertAiPromptbausteinRoutine(BS.Shared.DataContracts.Feature.AI.AiPromptbausteinRoutineDC routine) { return base.Channel.InsertAiPromptbausteinRoutine(routine); } - public System.Collections.Generic.List UpdateAiPromptbausteinFolder(System.Collections.Generic.List folders) + public BS.Shared.DataContracts.Feature.AI.AiPromptbausteinFolderDC UpdateAiPromptbausteinFolder(BS.Shared.DataContracts.Feature.AI.AiPromptbausteinFolderDC folders) { return base.Channel.UpdateAiPromptbausteinFolder(folders); } - public System.Collections.Generic.List UpdateAiPromptbausteinPrompt(System.Collections.Generic.List prompts) + public BS.Shared.DataContracts.Feature.AI.AiPromptbausteinPromptDC UpdateAiPromptbausteinPrompt(BS.Shared.DataContracts.Feature.AI.AiPromptbausteinPromptDC prompts) { return base.Channel.UpdateAiPromptbausteinPrompt(prompts); } - public System.Collections.Generic.List UpdateAiPromptbausteinRoutine(System.Collections.Generic.List routine) + public BS.Shared.DataContracts.Feature.AI.AiPromptbausteinRoutineDC UpdateAiPromptbausteinRoutine(BS.Shared.DataContracts.Feature.AI.AiPromptbausteinRoutineDC routine) { return base.Channel.UpdateAiPromptbausteinRoutine(routine); } - public void DeleteAiPromptbausteinFolder(System.Collections.Generic.Dictionary oid2version) + public void DeleteAiPromptbausteinFolder(BS.Shared.DataContracts.Feature.AI.AiPromptbausteinFolderDC folder) { - base.Channel.DeleteAiPromptbausteinFolder(oid2version); + base.Channel.DeleteAiPromptbausteinFolder(folder); } - public void DeleteAiPromptbausteinPrompt(System.Collections.Generic.Dictionary oid2version) + public void DeleteAiPromptbausteinPrompt(BS.Shared.DataContracts.Feature.AI.AiPromptbausteinPromptDC prompt) { - base.Channel.DeleteAiPromptbausteinPrompt(oid2version); + base.Channel.DeleteAiPromptbausteinPrompt(prompt); } - public void DeleteAiPromptbausteinRoutine(System.Collections.Generic.Dictionary oid2version) + public void DeleteAiPromptbausteinRoutine(BS.Shared.DataContracts.Feature.AI.AiPromptbausteinRoutineDC routine) { - base.Channel.DeleteAiPromptbausteinRoutine(oid2version); + base.Channel.DeleteAiPromptbausteinRoutine(routine); } public BS.Shared.DataContracts.Feature.AI.Functions.ServiceRecords.AiFunctionDocResponse ExecuteAiFunctionServiceRecordDocumentation(BS.Shared.DataContracts.Feature.AI.Functions.ServiceRecords.AiFunctionDocRequest request) diff --git a/BeWo/View/Detail/AI/AiPromptbausteinComplexTreeView.xaml b/BeWo/View/Detail/AI/AiPromptbausteinComplexTreeView.xaml index 0a425bf45..8e09dca56 100644 --- a/BeWo/View/Detail/AI/AiPromptbausteinComplexTreeView.xaml +++ b/BeWo/View/Detail/AI/AiPromptbausteinComplexTreeView.xaml @@ -12,6 +12,7 @@ xmlns:templateselectors="clr-namespace:BeWo.View.TemplateSelectors" xmlns:view="clr-namespace:BeWo.View" xmlns:vm="clr-namespace:BeWo.ViewModel" + x:Name="root" d:DataContext="{d:DesignInstance Type=administration:AiPromptbausteinComplexTreeViewModel, IsDesignTimeCreatable=True}" d:DesignHeight="450" @@ -25,18 +26,62 @@ - + TargetType="ListBoxItem" /> + + CornerRadius="5" + Tag="{Binding DataContext, RelativeSource={RelativeSource AncestorType=dxe:ListBoxEdit}}"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -84,9 +129,15 @@ + Padding="0"> + + + + + + (i) @@ -123,15 +174,52 @@ - + - + CornerRadius="5" + Tag="{Binding DataContext, RelativeSource={RelativeSource AncestorType=dxe:ListBoxEdit}}"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -179,14 +267,6 @@ - - - (i) - - - 3 Schritte · 2 min + + + + + + - + - + - + - - - - - - - - - - - - - - - - - @@ -515,42 +583,17 @@ - + - - - - - - - - - - - - - - - - - - - - - - @@ -578,31 +621,11 @@ - + - - - - - - - - - - - - - - - - - diff --git a/BeWo/View/Detail/AI/AiPromptbausteinComplexTreeView.xaml.cs b/BeWo/View/Detail/AI/AiPromptbausteinComplexTreeView.xaml.cs index fe74b91d1..8e3572ee5 100644 --- a/BeWo/View/Detail/AI/AiPromptbausteinComplexTreeView.xaml.cs +++ b/BeWo/View/Detail/AI/AiPromptbausteinComplexTreeView.xaml.cs @@ -49,8 +49,6 @@ namespace BeWo.View.Detail.AI public override bool IsDirty => ViewModel is object && ViewModel.IsDirty; - protected override void Save() => ViewModel.SaveVMList(); - private void OnPreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e) { TreeViewItem treeViewItem = VisualUpwardSearch(e.OriginalSource as DependencyObject); @@ -118,7 +116,6 @@ namespace BeWo.View.Detail.AI private void ListBox_ContextMenuOpening(object sender, ContextMenuEventArgs e) { ViewModel.UpdatePromptCommands(); - favorite.Header = ((ViewModel.SelectedItem as AiPromptbausteinPromptVM)?.IsFavorite ?? false) ? "Favorit entfernen" : "Favorit hinzufügen"; } private void Hyperlink_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e) @@ -143,7 +140,9 @@ namespace BeWo.View.Detail.AI { if(e.OriginalSource is TabControl) { - ViewModel.SelectedItem = null; + //listBoxEdit1.UnSelectAll(); + //listBoxEdit2.UnSelectAll(); + listBoxEdit3.UnSelectAll(); } } } diff --git a/BeWo/ViewModel/AiPromptbausteinFolderVM.cs b/BeWo/ViewModel/AiPromptbausteinFolderVM.cs index debd70390..daf080816 100644 --- a/BeWo/ViewModel/AiPromptbausteinFolderVM.cs +++ b/BeWo/ViewModel/AiPromptbausteinFolderVM.cs @@ -85,7 +85,24 @@ namespace BeWo.ViewModel public AiPromptbausteinFolderListVM SubFolders { get => _SubFolders; - set => SetProperty(ref _SubFolders, value, nameof(SubFolders)); + set + { + var success = SetProperty(ref _SubFolders, value, nameof(SubFolders)); + if (!success) + return; + + _SubFolders.VMList.ListChanged += (s, e) => { + FirePropertyChanged(nameof(TotalPromptCount)); + FirePropertyChanged(nameof(TotalRoutineCount)); + FirePropertyChanged(nameof(AlleFolderItems)); + + if (e.ListChangedType == System.ComponentModel.ListChangedType.ItemChanged) + return; + + FirePropertyChanged(nameof(Prompts)); + FirePropertyChanged(nameof(Routines)); + }; + } } public AiPromptbausteinPromptListVM SubPrompts @@ -287,6 +304,8 @@ namespace BeWo.ViewModel public override void UpdateByDataContract(AiPromptbausteinFolderDC pDataContract) { + DataContract = pDataContract; + Title = pDataContract.Title; Description = pDataContract.Description; IsPublic = pDataContract.IsPublic; diff --git a/BeWo/ViewModel/AiPromptbausteinPromptVM.cs b/BeWo/ViewModel/AiPromptbausteinPromptVM.cs index 9a935c4cc..9b08b1d44 100644 --- a/BeWo/ViewModel/AiPromptbausteinPromptVM.cs +++ b/BeWo/ViewModel/AiPromptbausteinPromptVM.cs @@ -125,7 +125,7 @@ namespace BeWo.ViewModel public bool IsInfoVisible { - get => IsOwnsoftPrompt && !string.IsNullOrWhiteSpace(OwnsoftRefLink) && IsSelected; + get => IsOwnsoftPrompt && !string.IsNullOrWhiteSpace(OwnsoftRefLink); } public FontWeight FontWeight @@ -138,6 +138,8 @@ namespace BeWo.ViewModel get => ShowPrompt && ShowPromptByTenant; } + public string FavoritenHeader => IsFavorite ? "Favorit entfernen" : "Favorit hinzufügen"; + protected override void InitByDataContract(AiPromptbausteinPromptDC pDataContract) { _Title = pDataContract.Title; @@ -176,6 +178,8 @@ namespace BeWo.ViewModel public override void UpdateByDataContract(AiPromptbausteinPromptDC pDataContract) { + DataContract = pDataContract; + Title = pDataContract.Title; Description = pDataContract.Description; ParentFolderOid = pDataContract.ParentFolderOid; diff --git a/BeWo/ViewModel/AiPromptbausteinRoutineStepVM.cs b/BeWo/ViewModel/AiPromptbausteinRoutineStepVM.cs index 4cf4660bf..b263d1247 100644 --- a/BeWo/ViewModel/AiPromptbausteinRoutineStepVM.cs +++ b/BeWo/ViewModel/AiPromptbausteinRoutineStepVM.cs @@ -53,6 +53,8 @@ namespace BeWo.ViewModel public override void UpdateByDataContract(AiPromptbausteinRoutineStepDC pDataContract) { + DataContract = pDataContract; + Position = pDataContract.Position; PromptReference = pDataContract.PromptReference; ReferenceVersion = pDataContract.ReferenceVersion; diff --git a/BeWo/ViewModel/AiPromptbausteinRoutineVM.cs b/BeWo/ViewModel/AiPromptbausteinRoutineVM.cs index bc7c5324a..4a7af1f24 100644 --- a/BeWo/ViewModel/AiPromptbausteinRoutineVM.cs +++ b/BeWo/ViewModel/AiPromptbausteinRoutineVM.cs @@ -91,6 +91,8 @@ namespace BeWo.ViewModel get => BeWoApp.HasLoggedOnUserRight(UserRightType.AiModulePromptbausteinShare); } + public string FavoritenHeader => IsFavorite ? "Favorit entfernen" : "Favorit hinzufügen"; + public override bool IsDirty => base.IsDirty || Steps.IsDirty; protected override void InitByDataContract(AiPromptbausteinRoutineDC pDataContract) @@ -126,6 +128,8 @@ namespace BeWo.ViewModel public override void UpdateByDataContract(AiPromptbausteinRoutineDC pDataContract) { + DataContract = pDataContract; + Title = pDataContract.Title; Description = pDataContract.Description; IsPublic = pDataContract.IsPublic; diff --git a/BeWo/ViewModel/ListViewModel/AiPromptbausteinRoutineStepListVM.cs b/BeWo/ViewModel/ListViewModel/AiPromptbausteinRoutineStepListVM.cs index d1649157f..934804e21 100644 --- a/BeWo/ViewModel/ListViewModel/AiPromptbausteinRoutineStepListVM.cs +++ b/BeWo/ViewModel/ListViewModel/AiPromptbausteinRoutineStepListVM.cs @@ -49,6 +49,8 @@ namespace BeWo.ViewModel.ListViewModel VMList.Add(vm); } } + + FirePropertyChanged(nameof(Count)); } } } \ No newline at end of file diff --git a/BeWo/ViewModel/VMFactory.cs b/BeWo/ViewModel/VMFactory.cs index 7f40f470d..64d55e855 100644 --- a/BeWo/ViewModel/VMFactory.cs +++ b/BeWo/ViewModel/VMFactory.cs @@ -994,6 +994,12 @@ namespace BeWo.ViewModel if (prompt.IsFavorite) favoriten.SubPrompts.VMList.Add(prompt); } + + foreach (var routine in folder.SubRoutines.VMList) + { + if(routine.IsFavorite) + favoriten.SubRoutines.VMList.Add(routine); + } } } } diff --git a/BeWo/ViewModel/View/AI/AiConversationChatViewModel.cs b/BeWo/ViewModel/View/AI/AiConversationChatViewModel.cs index 081d77657..31050c067 100644 --- a/BeWo/ViewModel/View/AI/AiConversationChatViewModel.cs +++ b/BeWo/ViewModel/View/AI/AiConversationChatViewModel.cs @@ -453,7 +453,7 @@ namespace BeWo.ViewModel.View.AI } public void AcceptSavePrompt() { - ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.InsertAiPromptbausteinPrompt(new List() { SavePromptVM.CommitToDataContract() }), cb => SavePromptVM = null, exc => SavePromptVM = null); + ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.InsertAiPromptbausteinPrompt(SavePromptVM.CommitToDataContract()), cb => SavePromptVM = null, exc => SavePromptVM = null); } public void CancelSavePrompt() { diff --git a/BeWo/ViewModel/View/AI/AiPromptbausteinComplexSelectionViewModel.cs b/BeWo/ViewModel/View/AI/AiPromptbausteinComplexSelectionViewModel.cs index ebbb46b48..ff17057d1 100644 --- a/BeWo/ViewModel/View/AI/AiPromptbausteinComplexSelectionViewModel.cs +++ b/BeWo/ViewModel/View/AI/AiPromptbausteinComplexSelectionViewModel.cs @@ -251,7 +251,7 @@ namespace BeWo.ViewModel.View.AI { var new_dc = new_vm.CommitToDataContract(); - ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.InsertAiPromptbausteinFolder(new List { new_dc }), + ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.InsertAiPromptbausteinFolder(new_dc), (new_dcs) => ReloadVMList()); }; @@ -274,7 +274,7 @@ namespace BeWo.ViewModel.View.AI { var edit_dc = edit_vm.CommitToDataContract(); - ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.UpdateAiPromptbausteinFolder(new List { edit_dc }), + ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.UpdateAiPromptbausteinFolder(edit_dc), (update_dc) => ReloadVMList()); }; @@ -291,12 +291,9 @@ namespace BeWo.ViewModel.View.AI if (result != MessageBoxResult.OK) return; - var oid2version = new Dictionary() - { - {sel_folder.DataContract.Oid.Value, sel_folder.DataContract.Version.Value} - }; + var delete_dc = sel_folder.CommitToDataContract(); - ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.DeleteAiPromptbausteinFolder(oid2version), + ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.DeleteAiPromptbausteinFolder(delete_dc), () => ReloadVMList()); } @@ -324,7 +321,7 @@ namespace BeWo.ViewModel.View.AI { var new_dc = new_vm.CommitToDataContract(); - ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.InsertAiPromptbausteinPrompt(new List { new_dc }), + ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.InsertAiPromptbausteinPrompt(new_dc), (new_dcs) => ReloadVMList()); }; @@ -347,7 +344,7 @@ namespace BeWo.ViewModel.View.AI { var edit_dc = edit_vm.CommitToDataContract(); - ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.UpdateAiPromptbausteinPrompt(new List { edit_dc }), + ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.UpdateAiPromptbausteinPrompt(edit_dc), (update_dc) => ReloadVMList()); }; @@ -364,12 +361,9 @@ namespace BeWo.ViewModel.View.AI if (result != MessageBoxResult.OK) return; - var oid2version = new Dictionary() - { - {sel_prompt.DataContract.Oid.Value, sel_prompt.DataContract.Version.Value} - }; + var delete_dc = sel_prompt.CommitToDataContract(); - ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.DeleteAiPromptbausteinPrompt(oid2version), + ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.DeleteAiPromptbausteinPrompt(delete_dc), () => ReloadVMList()); } void ChangeFavoritenStatePrompt() @@ -378,7 +372,7 @@ namespace BeWo.ViewModel.View.AI sel_prompt.IsFavorite = !sel_prompt.IsFavorite; var edit_dc = sel_prompt.CommitToDataContract(); - ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.UpdateAiPromptbausteinPrompt(new List { edit_dc }), + ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.UpdateAiPromptbausteinPrompt(edit_dc), (update_dc) => ReloadVMList()); } diff --git a/BeWo/ViewModel/View/Administration/AiPromptbausteinComplexTreeViewModel.cs b/BeWo/ViewModel/View/Administration/AiPromptbausteinComplexTreeViewModel.cs index 326ea6ec7..615e5e584 100644 --- a/BeWo/ViewModel/View/Administration/AiPromptbausteinComplexTreeViewModel.cs +++ b/BeWo/ViewModel/View/Administration/AiPromptbausteinComplexTreeViewModel.cs @@ -6,6 +6,7 @@ using BS.Shared.DataContracts.Compact; using BS.Shared.DataContracts.Feature.AI; using BS.Shared.Extensions.CustomInterfaces; using DevExpress.Mvvm; +using DevExpress.Utils.Extensions; using DevExpress.Xpf.Layout.Core; using System; using System.Collections.Generic; @@ -15,6 +16,7 @@ using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Input; +using static DevExpress.Utils.Drawing.Helpers.NativeMethods; namespace BeWo.ViewModel.View.Administration { @@ -50,14 +52,24 @@ namespace BeWo.ViewModel.View.Administration public DelegateCommand DeleteRoutineCommand { get; private set; } public DelegateCommand ChangeFavoritenStateRoutineCommand { get; private set; } + public bool CanEditPromptbausteine { get; set; } public AiPromptbausteinFolderVM SelectedFolder { get => _SelectedFolder; - set => SetProperty(ref _SelectedFolder, value, nameof(SelectedFolder)); + set + { + SetProperty(ref _SelectedFolder, value, nameof(SelectedFolder)); + + if (SelectedItem is AiPromptbausteinPromptVM vm) + { + vm.IsSelected = false; + SelectedItem = null; + } + } } - + public AbstractBaseVM SelectedItem { get => _SelectedItem; @@ -104,11 +116,11 @@ namespace BeWo.ViewModel.View.Administration { get { - return Folders?.ContainsDirtyObject() ?? false; + return false; } } public bool HasCopiedFolder => CopiedFolder is object; - public bool HasCopiedPrompt => CopiedPrompt is object; + public bool HasCopiedPrompt => CopiedPrompt is object; public CompactEmployeeDC CurrentEmployee => BeWoApp.CompactLoggedOnEmployee; public void UpdateFolderCommands() @@ -118,7 +130,7 @@ namespace BeWo.ViewModel.View.Administration CopyFolderCommand.RaiseCanExecuteChanged(); PasteFolderCommand.RaiseCanExecuteChanged(); DeleteFolderCommand.RaiseCanExecuteChanged(); - } + } public void UpdatePromptCommands() { OpenAddPromptDialogCommand.RaiseCanExecuteChanged(); @@ -133,61 +145,6 @@ namespace BeWo.ViewModel.View.Administration ChangeFavoritenStateRoutineCommand.RaiseCanExecuteChanged(); } - public void SaveVMList() - { - if (!IsDirty) - return; - - // DFS -> 1. Sobald Knoten gefunden wird mit IsNew=true: Teilbaum als neu markieren - // 2. Sobald Knoten gefunden wird mit IsNew=false && IsDirty=true: Knoten als update markieren - // 3. Checken, welche Knoten gelöscht wurden - - var toadd_folder = new List(); - var toadd_prompts = new List(); - var toupdate_folder = new List(); - var toupdate_prompt = new List(); - DFS_Search_AddUpdate(Folders, ref toadd_folder, ref toadd_prompts, ref toupdate_folder, ref toupdate_prompt); - - var todelete_folder = new List(); - var todelete_prompt = new List(); - DFS_Search_Delete(Folders, ref todelete_folder, ref todelete_prompt); - - var toadd_folder_dcs = toadd_folder.Select(x => x.CommitToDataContract()); - var toupdate_folder_dcs = toupdate_folder.Select(x => x.CommitToDataContract()); - - var actions = new List>(); - - if (toadd_folder.Any()) - actions.Add(x => x.InsertAiPromptbausteinFolder(toadd_folder_dcs.ToList())); - - if (toadd_prompts.Any()) - actions.Add(x => x.InsertAiPromptbausteinPrompt(toadd_prompts.ToList())); - - if (toupdate_folder_dcs.Any()) - { - foreach (var folder_dc in toupdate_folder_dcs) - { - folder_dc.SubPrompts = null; - folder_dc.SubFolders = null; - } - - actions.Add(x => x.UpdateAiPromptbausteinFolder(toupdate_folder_dcs.ToList())); - } - - if (toupdate_prompt.Any()) - actions.Add(x => x.UpdateAiPromptbausteinPrompt(toupdate_prompt.ToList())); - - if (todelete_folder.Any()) - actions.Add(x => x.DeleteAiPromptbausteinFolder(todelete_folder.ToDictionary(x1 => x1.Oid.Value, x2 => x2.Version.Value))); - - if (todelete_prompt.Any()) - actions.Add(x => x.DeleteAiPromptbausteinPrompt(todelete_prompt.ToDictionary(x1 => x1.Oid.Value, x2 => x2.Version.Value))); - - ServiceFacade.DoMultipleAiEnhancedServicesAsync(actions, () => - { - ReloadVMList(); - }); - } internal void ReloadVMList() { VMFactory.CreateAiPromptbausteinFolderListVMAsync( @@ -203,76 +160,6 @@ namespace BeWo.ViewModel.View.Administration }); } - void DFS_Search_AddUpdate(AiPromptbausteinFolderListVM folders, ref List toadd_Folder, ref List toadd_Prompts, ref List toupdate_Folder, ref List toupdate_Prompt) - { - foreach (var node in folders.VMList) - { - // Favoriten ignorieren - if (node.DataContract.Oid is long oid && oid < -4) - continue; - - // Öffentlich - if (node.DataContract.Oid is long oid2 && oid2 < -1){ - DFS_Search_UpdatePromptFavorite(node.SubFolders, ref toadd_Folder, ref toadd_Prompts, ref toupdate_Folder, ref toupdate_Prompt); - if (node.SubPrompts.ChangedCount > 0) - toupdate_Prompt.AddRange(node.SubPrompts.CommitChanged()); - continue; - } - - // Eigene - if (node.IsNew) - { - toadd_Folder.Add(node); - } - else - { - if (node.IsDirty) - toupdate_Folder.Add(node); - - if (node.HasSubFolders) - DFS_Search_AddUpdate(node.SubFolders, ref toadd_Folder, ref toadd_Prompts, ref toupdate_Folder, ref toupdate_Prompt); - - if (node.SubPrompts.AddedCount > 0) - toadd_Prompts.AddRange(node.SubPrompts.CommitAdded()); - - if (node.SubPrompts.ChangedCount > 0) - toupdate_Prompt.AddRange(node.SubPrompts.CommitChanged()); - } - } - } - void DFS_Search_UpdatePromptFavorite(AiPromptbausteinFolderListVM folders, ref List toadd_Folder, ref List toadd_Prompts, ref List toupdate_Folder, ref List toupdate_Prompt) - { - foreach (var node in folders.VMList) - { - if (node.HasSubFolders) - DFS_Search_UpdatePromptFavorite(node.SubFolders, ref toadd_Folder, ref toadd_Prompts, ref toupdate_Folder, ref toupdate_Prompt); - - if (node.SubPrompts.ChangedCount > 0) - toupdate_Prompt.AddRange(node.SubPrompts.CommitChanged()); - } - } - void DFS_Search_Delete(AiPromptbausteinFolderListVM folders, ref List todelete_Folder, ref List todelete_Prompt) - { - foreach (var node_dc in folders.DCBackup) - { - if (node_dc.Oid is long oid && oid < -1) - continue; - - if (folders.VMList.FirstOrDefault(vm => vm.DataContract == node_dc) is AiPromptbausteinFolderVM node_vm) - { - if (node_vm.SubFolders.DCBackup is object && node_vm.SubFolders.DCBackup.Count > 0) - DFS_Search_Delete(node_vm.SubFolders, ref todelete_Folder, ref todelete_Prompt); - - if (node_vm.SubPrompts.RemovedCount > 0) - todelete_Prompt.AddRange(node_vm.SubPrompts.GetRemoved()); - } - else - { - todelete_Folder.Add(node_dc); - } - } - } - void OpenAddFolderDialog() { var sel_folder = SelectedFolder; @@ -290,8 +177,15 @@ namespace BeWo.ViewModel.View.Administration vm.Accept_Button_Clicked += (s, e) => { - sel_folder.SubFolders.VMList.Add(new_vm); - sel_folder.IsExpanded = true; + var dc = new_vm.CommitToDataContract(); + + ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.InsertAiPromptbausteinFolder(dc), + new_dc => + { + new_vm.UpdateByDataContract(new_dc); + sel_folder.SubFolders.VMList.Add(new_vm); + sel_folder.IsExpanded = true; + }); }; WindowService.Show(vm); @@ -301,6 +195,8 @@ namespace BeWo.ViewModel.View.Administration var sel_folder = SelectedFolder; var sel_dc = sel_folder.CopyToEmptyDataContract(); sel_dc.CanEdit = SelectedFolder.CanEdit; + sel_dc.Oid = sel_folder.DataContract.Oid; + sel_dc.Version = sel_folder.DataContract.Version; var edit_vm = new AiPromptbausteinFolderVM(sel_dc); var vm = new AiPromptbausteinFolderViewModel(edit_vm, false); @@ -308,7 +204,12 @@ namespace BeWo.ViewModel.View.Administration vm.Accept_Button_Clicked += (s, e) => { var edit_dc = edit_vm.CommitToDataContract(); - sel_folder.UpdateByDataContract(edit_dc); + + ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.UpdateAiPromptbausteinFolder(edit_dc), + new_dc => + { + sel_folder.UpdateByDataContract(new_dc); + }); }; WindowService.Show(vm); @@ -332,7 +233,9 @@ namespace BeWo.ViewModel.View.Administration if (result != MessageBoxResult.OK) return; - parent.SubFolders.VMList.Remove(sel_folder); + var delete_dc = sel_folder.CommitToDataContract(); + ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.DeleteAiPromptbausteinFolder(delete_dc), + () => parent.SubFolders.VMList.Remove(sel_folder)); } bool canOpenAddFolderDialog() @@ -374,8 +277,15 @@ namespace BeWo.ViewModel.View.Administration vm.Accept_Button_Clicked += (s, e) => { - sel_folder.SubPrompts.VMList.Add(new_vm); - SelectedItem = new_vm; + var dc = new_vm.CommitToDataContract(); + + ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.InsertAiPromptbausteinPrompt(dc), + new_dc => + { + new_vm.UpdateByDataContract(new_dc); + sel_folder.SubPrompts.VMList.Add(new_vm); + SelectedItem = new_vm; + }); }; WindowService.Show(vm); @@ -389,6 +299,8 @@ namespace BeWo.ViewModel.View.Administration var sel_dc = sel_prompt.CopyToEmptyDataContract(); sel_dc.CanEdit = sel_prompt.CanEdit; + sel_dc.Oid = sel_prompt.DataContract.Oid; + sel_dc.Version = sel_prompt.DataContract.Version; var edit_vm = new AiPromptbausteinPromptVM(sel_dc); var vm = new AiPromptbausteinPromptViewModel(edit_vm, false); @@ -396,9 +308,13 @@ namespace BeWo.ViewModel.View.Administration vm.Accept_Button_Clicked += (s, e) => { var edit_dc = edit_vm.CommitToDataContract(); - sel_prompt.UpdateByDataContract(edit_dc); - UpdateSelectedPromptFavorite(sel_prompt); + ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.UpdateAiPromptbausteinPrompt(edit_dc), + new_dc => + { + sel_prompt.UpdateByDataContract(new_dc); + UpdateSelectedPromptFavorite(sel_prompt); + }); }; WindowService.Show(vm); @@ -474,7 +390,25 @@ namespace BeWo.ViewModel.View.Administration if (result != MessageBoxResult.OK) return; - folder.SubPrompts.VMList.Remove(sel_prompt); + if (sel_prompt.IsFavorite) + { + sel_prompt.IsFavorite = false; + UpdateSelectedPromptFavorite(); + } + + var delete_dc = sel_prompt.CommitToDataContract(); + ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.DeleteAiPromptbausteinPrompt(delete_dc), + () => + { + if (folder.SubPrompts.VMList.Contains(sel_prompt)) + { + folder.SubPrompts.VMList.Remove(sel_prompt); + } + else + { + ReloadVMList(); + } + }); } void ChangeFavoritenStatePrompt() @@ -483,7 +417,14 @@ namespace BeWo.ViewModel.View.Administration sel_prompt.IsFavorite = !sel_prompt.IsFavorite; - UpdateSelectedPromptFavorite(sel_prompt); + var edit_dc = sel_prompt.CommitToDataContract(); + + ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.UpdateAiPromptbausteinPrompt(edit_dc), + new_dc => + { + sel_prompt.UpdateByDataContract(new_dc); + UpdateSelectedPromptFavorite(sel_prompt); + }); } bool canOpenAddPromptDialog() @@ -528,8 +469,15 @@ namespace BeWo.ViewModel.View.Administration vm.Accept_Button_Clicked += (s, e) => { - sel_folder.SubRoutines.VMList.Add(new_vm); - SelectedItem = new_vm; + var dc = new_vm.CommitToDataContract(); + + ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.InsertAiPromptbausteinRoutine(dc), + new_dc => + { + new_vm.UpdateByDataContract(new_dc); + sel_folder.SubRoutines.VMList.Add(new_vm); + SelectedItem = new_vm; + }); }; WindowService.Show(vm); @@ -543,6 +491,8 @@ namespace BeWo.ViewModel.View.Administration var sel_dc = sel_prompt.CopyToEmptyDataContract(); sel_dc.CanEdit = sel_prompt.CanEdit; + sel_dc.Oid = sel_prompt.DataContract.Oid; + sel_dc.Version = sel_prompt.DataContract.Version; var edit_vm = new AiPromptbausteinRoutineVM(sel_dc); var vm = new AiPromptbausteinRoutineViewModel(edit_vm, Folders, false); @@ -550,9 +500,13 @@ namespace BeWo.ViewModel.View.Administration vm.Accept_Button_Clicked += (s, e) => { var edit_dc = edit_vm.CommitToDataContract(); - sel_prompt.UpdateByDataContract(edit_dc); - UpdateSelectedRoutineFavorite(sel_prompt); + ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.UpdateAiPromptbausteinRoutine(edit_dc), + new_dc => + { + sel_prompt.UpdateByDataContract(new_dc); + UpdateSelectedRoutineFavorite(sel_prompt); + }); }; WindowService.Show(vm); @@ -568,7 +522,25 @@ namespace BeWo.ViewModel.View.Administration if (result != MessageBoxResult.OK) return; - folder.SubRoutines.VMList.Remove(sel_prompt); + if (sel_prompt.IsFavorite) + { + sel_prompt.IsFavorite = false; + UpdateSelectedRoutineFavorite(); + } + + var delete_dc = sel_prompt.CommitToDataContract(); + ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.DeleteAiPromptbausteinRoutine(delete_dc), + () => + { + if (folder.SubRoutines.VMList.Contains(sel_prompt)) + { + folder.SubRoutines.VMList.Remove(sel_prompt); + } + else + { + ReloadVMList(); + } + }); } void ChangeFavoritenStateRoutine() { @@ -576,7 +548,14 @@ namespace BeWo.ViewModel.View.Administration sel_routine.IsFavorite = !sel_routine.IsFavorite; - UpdateSelectedRoutineFavorite(sel_routine); + var edit_dc = sel_routine.CommitToDataContract(); + + ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.UpdateAiPromptbausteinRoutine(edit_dc), + new_dc => + { + sel_routine.UpdateByDataContract(new_dc); + UpdateSelectedRoutineFavorite(sel_routine); + }); } bool canOpenAddRoutineDialog() => CanEditPromptbausteine && (SelectedFolder?.CanAddPrompt ?? false); diff --git a/BeWo/ViewModel/View/Administration/AiPromptbausteinPromptViewModel.cs b/BeWo/ViewModel/View/Administration/AiPromptbausteinPromptViewModel.cs index 6d3046e3d..195c38693 100644 --- a/BeWo/ViewModel/View/Administration/AiPromptbausteinPromptViewModel.cs +++ b/BeWo/ViewModel/View/Administration/AiPromptbausteinPromptViewModel.cs @@ -27,7 +27,7 @@ namespace BeWo.ViewModel.View.Administration protected override bool canAccept() { - return (_IsNew || ViewModel.IsDirty) && !string.IsNullOrWhiteSpace(ViewModel.Title); + return (_IsNew || ViewModel.IsDirty) && !string.IsNullOrWhiteSpace(ViewModel.Title) && !string.IsNullOrWhiteSpace(ViewModel.Prompt); } } } diff --git a/Data/Data.csproj b/Data/Data.csproj index de9c92283..378f7b1f2 100644 --- a/Data/Data.csproj +++ b/Data/Data.csproj @@ -876,6 +876,8 @@ + + Designer diff --git a/Data/Entities/AiPromptbausteinFolder.cs b/Data/Entities/AiPromptbausteinFolder.cs index aba17b7bf..25c69bb4c 100644 --- a/Data/Entities/AiPromptbausteinFolder.cs +++ b/Data/Entities/AiPromptbausteinFolder.cs @@ -32,5 +32,7 @@ namespace BeWo.Data.Entities public virtual IList SubFolders { get; set; } = new List(); public virtual IList SubPrompts { get; set; } = new List(); + + public virtual IList SubRoutines { get; set; } = new List(); } } diff --git a/Data/Entities/AiPromptbausteinRoutine.cs b/Data/Entities/AiPromptbausteinRoutine.cs index 87fa12048..b18558a42 100644 --- a/Data/Entities/AiPromptbausteinRoutine.cs +++ b/Data/Entities/AiPromptbausteinRoutine.cs @@ -27,12 +27,10 @@ namespace BeWo.Data.Entities public virtual int Position { get; set; } - public virtual bool IsFavorite { get; set; } + public virtual IList UserFavorites { get; set; } = new List(); public virtual AiActionType ActionType { get; set; } - public virtual bool CanEdit { get; set; } - - public virtual List Steps { get; set; } + public virtual IList Steps { get; set; } } } diff --git a/Data/Mappings/AiPromptbausteinFolder.hbm.xml b/Data/Mappings/AiPromptbausteinFolder.hbm.xml index 39f90c933..3e8531be5 100644 --- a/Data/Mappings/AiPromptbausteinFolder.hbm.xml +++ b/Data/Mappings/AiPromptbausteinFolder.hbm.xml @@ -30,5 +30,10 @@ + + + + + diff --git a/Data/Mappings/AiPromptbausteinRoutine.hbm.xml b/Data/Mappings/AiPromptbausteinRoutine.hbm.xml new file mode 100644 index 000000000..07719e366 --- /dev/null +++ b/Data/Mappings/AiPromptbausteinRoutine.hbm.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Data/Mappings/AiPromptbausteinRoutineStep.hbm.xml b/Data/Mappings/AiPromptbausteinRoutineStep.hbm.xml new file mode 100644 index 000000000..f303faef4 --- /dev/null +++ b/Data/Mappings/AiPromptbausteinRoutineStep.hbm.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/Host/Web.Deploy.config b/Host/Web.Deploy.config index 33f59a96b..dff91cbfe 100644 --- a/Host/Web.Deploy.config +++ b/Host/Web.Deploy.config @@ -148,8 +148,7 @@ - - + diff --git a/Model/Changes_2026-05-12 AiPromptbausteinRoutine Favoriten.txt b/Model/Changes_2026-05-12 AiPromptbausteinRoutine Favoriten.txt new file mode 100644 index 000000000..f431be174 --- /dev/null +++ b/Model/Changes_2026-05-12 AiPromptbausteinRoutine Favoriten.txt @@ -0,0 +1,27 @@ +INSERT INTO `.executedscripts` +VALUES ('Changes_2026-05-12 AiPromptbausteinRoutine Favoriten', CURDATE()); + +ALTER TABLE `aipromptbauteinroutine` +RENAME TO `aipromptbausteinroutine` ; + +CREATE TABLE `aipromptbausteinroutine2empfavorite` ( + `AiPromptbausteinRoutineOid` bigint NOT NULL, + `EmployeeOid` bigint NOT NULL, + PRIMARY KEY (`AiPromptbausteinRoutineOid`,`EmployeeOid`), + CONSTRAINT `FK_AIPROMPTBAUSTEINROUTINE2EMPFAV_AIPROMPT` FOREIGN KEY (`AiPromptbausteinRoutineOid`) REFERENCES `aipromptbausteinroutine` (`Oid`), + CONSTRAINT `FK_AIPROMPTBAUSTEINROUTINE2EMPFAV_APPUSER` FOREIGN KEY (`EmployeeOid`) REFERENCES `employee` (`Oid`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +ALTER TABLE `aipromptbausteinroutinestep` +ADD COLUMN `RoutineOid` BIGINT NULL AFTER `PromptReferenceVersion`, +ADD INDEX `FK_AIPROMPTROUTINESTEP_ROUTINE_idx` (`RoutineOid` ASC) VISIBLE; +; +ALTER TABLE `aipromptbausteinroutinestep` +ADD CONSTRAINT `FK_AIPROMPTROUTINESTEP_ROUTINE` + FOREIGN KEY (`RoutineOid`) + REFERENCES `aipromptbausteinroutine` (`Oid`) + ON DELETE CASCADE + ON UPDATE CASCADE; + +ALTER TABLE `aipromptbausteinroutine` +DROP COLUMN `IsFavorite`; \ No newline at end of file diff --git a/Service/BusinessLogic/AiPromptbausteinFolderLogic.cs b/Service/BusinessLogic/AiPromptbausteinFolderLogic.cs new file mode 100644 index 000000000..f8f016e49 --- /dev/null +++ b/Service/BusinessLogic/AiPromptbausteinFolderLogic.cs @@ -0,0 +1,69 @@ +using BeWo.Data.Access; +using BeWo.Data.Entities; +using BeWo.Service.DCEntityMapper; +using BS.Shared.DataContracts.Feature.AI; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BeWo.Service.BusinessLogic +{ + public class AiPromptbausteinFolderLogic : GenericBusinessLogic + { + public override IDCEntityMapper Mapper => MapperFactory.AiPromptbausteinFolder; + + public override AiPromptbausteinFolderDC Insert(AiPromptbausteinFolderDC dc) + { + var canEdit = dc.CanEdit; + var canAddFolder = dc.CanAddFolder; + var canAddPrompt = dc.CanAddPrompt; + var canAddRoutine = dc.CanAddRoutine; + + var dc2 = base.Insert(dc); + + dc2.CanEdit = canEdit; + dc2.CanAddFolder = canAddFolder; + dc2.CanAddPrompt = canAddPrompt; + dc2.CanAddRoutine = canAddRoutine; + + return dc2; + } + + public override AiPromptbausteinFolderDC Update(AiPromptbausteinFolderDC dc) + { + var canEdit = dc.CanEdit; + var canAddFolder = dc.CanAddFolder; + var canAddPrompt = dc.CanAddPrompt; + var canAddRoutine = dc.CanAddRoutine; + + var dc2 = base.Update(dc); + + dc2.CanEdit = canEdit; + dc2.CanAddFolder = canAddFolder; + dc2.CanAddPrompt = canAddPrompt; + dc2.CanAddRoutine = canAddRoutine; + + return dc2; + } + + public override void Deactivate(AiPromptbausteinFolderDC dc) + { + if(dc.SubFolders?.Any() ?? false) + { + foreach(var subfolder in dc.SubFolders) + { + Deactivate(subfolder); + } + } + + base.Deactivate(dc); + } + + public override bool Delete(AiPromptbausteinFolderDC dc) + { + throw new NotImplementedException(); + } + } +} diff --git a/Service/BusinessLogic/AiPromptbausteinPromptLogic.cs b/Service/BusinessLogic/AiPromptbausteinPromptLogic.cs new file mode 100644 index 000000000..697130c1f --- /dev/null +++ b/Service/BusinessLogic/AiPromptbausteinPromptLogic.cs @@ -0,0 +1,38 @@ +using BeWo.Data.Entities; +using BeWo.Service.DCEntityMapper; +using BS.Shared.DataContracts.Feature.AI; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BeWo.Service.BusinessLogic +{ + public class AiPromptbausteinPromptLogic : GenericBusinessLogic + { + public override IDCEntityMapper Mapper => MapperFactory.AiPromptbausteinPrompt; + + public override AiPromptbausteinPromptDC Insert(AiPromptbausteinPromptDC dc) + { + var canEdit = dc.CanEdit; + + var dc2 = base.Insert(dc); + + dc2.CanEdit = canEdit; + + return dc2; + } + + public override AiPromptbausteinPromptDC Update(AiPromptbausteinPromptDC dc) + { + var canEdit = dc.CanEdit; + + var dc2 = base.Update(dc); + + dc2.CanEdit = canEdit; + + return dc2; + } + } +} diff --git a/Service/BusinessLogic/AiPromptbausteinRoutineLogic.cs b/Service/BusinessLogic/AiPromptbausteinRoutineLogic.cs new file mode 100644 index 000000000..f4faf06c2 --- /dev/null +++ b/Service/BusinessLogic/AiPromptbausteinRoutineLogic.cs @@ -0,0 +1,16 @@ +using BeWo.Data.Entities; +using BeWo.Service.DCEntityMapper; +using BS.Shared.DataContracts.Feature.AI; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BeWo.Service.BusinessLogic +{ + public class AiPromptbausteinRoutineLogic : GenericBusinessLogic + { + public override IDCEntityMapper Mapper => MapperFactory.AiPromptbausteinRoutine; + } +} diff --git a/Service/BusinessLogic/GenericBusinessLogic.cs b/Service/BusinessLogic/GenericBusinessLogic.cs new file mode 100644 index 000000000..881eee5ec --- /dev/null +++ b/Service/BusinessLogic/GenericBusinessLogic.cs @@ -0,0 +1,64 @@ +using BeWo.Data.Access; +using BeWo.Data.Entities; +using BeWo.Service.Core; +using BeWo.Service.DCEntityMapper; +using BS.Shared.DataContracts; +using BS.Shared.DataContracts.Feature.AI; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BeWo.Service.BusinessLogic +{ + public abstract class GenericBusinessLogic where TDataContract : BeWoDataContract, new () where TEntity : BeWoEntityBase, new () + { + public abstract IDCEntityMapper Mapper { get; } + + public TDataContract Get(long oid) + { + var entity = getEntity(oid); + var dc = Mapper.MapToNewDC(entity); + return dc; + } + + public virtual TDataContract Insert(TDataContract dc) + { + var entity = Mapper.MapToNewEntity(dc); + DAOFactory.GenericDAO.Insert(entity); + var dc2 = Mapper.MapToNewDC(entity); + return dc2; + } + + public virtual TDataContract Update(TDataContract dc) + { + var entity = getEntity(dc.Oid.Value); + entity = Mapper.MergeWithEntity(dc, entity); + DAOFactory.GenericDAO.Update(entity); + var dc2 = Mapper.MapToNewDC(entity); + return dc2; + } + + public virtual void Deactivate(TDataContract dc) + { + var entity = getEntity(dc.Oid.Value); + ServiceLogic.ConcurrencyCheck(dc.Version, entity); + DAOFactory.GenericDAO.SetActivationType(entity, BS.Shared.ActivationTypeId.Deleted); + } + + public virtual bool Delete(TDataContract dc) + { + var entity = getEntity(dc.Oid.Value); + ServiceLogic.ConcurrencyCheck(dc.Version, entity); + DAOFactory.GenericDAO.Delete(entity); + return true; + } + + private TEntity getEntity(long oid) + { + var entity = DAOFactory.GenericDAO.LoadByID(oid); + return entity; + } + } +} diff --git a/Service/DCEntityMapper/AiPromptbausteinFolderDC_AiPromptbausteinFolder.cs b/Service/DCEntityMapper/AiPromptbausteinFolderDC_AiPromptbausteinFolder.cs index 89b4c704d..6e4d5d104 100644 --- a/Service/DCEntityMapper/AiPromptbausteinFolderDC_AiPromptbausteinFolder.cs +++ b/Service/DCEntityMapper/AiPromptbausteinFolderDC_AiPromptbausteinFolder.cs @@ -24,6 +24,7 @@ namespace BeWo.Service.DCEntityMapper pDataContract.ActionType = pEntity.ActionType; pDataContract.SubFolders = MapperFactory.AiPromptbausteinFolder.MapToNewDCs(pEntity.SubFolders); pDataContract.SubPrompts = MapperFactory.AiPromptbausteinPrompt.MapToNewDCs(pEntity.SubPrompts); + pDataContract.SubRoutines = MapperFactory.AiPromptbausteinRoutine.MapToNewDCs(pEntity.SubRoutines); if (pEntity.CreatorOid is long oid) pDataContract.Creator = new EmployeeServiceImp().GetActiveCompactEmployeeWithOid(oid); @@ -51,6 +52,9 @@ namespace BeWo.Service.DCEntityMapper if (pDataContract.SubPrompts is object) MapperFactory.AiPromptbausteinPrompt.MergeWithEntitys(pDataContract.SubPrompts, pEntity.SubPrompts); + if (pDataContract.SubRoutines is object) + MapperFactory.AiPromptbausteinRoutine.MergeWithEntitys(pDataContract.SubRoutines, pEntity.SubRoutines); + return pEntity; } } diff --git a/Service/DCEntityMapper/AiPromptbausteinRoutineDC_AiPromptbausteinRoutine.cs b/Service/DCEntityMapper/AiPromptbausteinRoutineDC_AiPromptbausteinRoutine.cs index e4322760e..6212a3e18 100644 --- a/Service/DCEntityMapper/AiPromptbausteinRoutineDC_AiPromptbausteinRoutine.cs +++ b/Service/DCEntityMapper/AiPromptbausteinRoutineDC_AiPromptbausteinRoutine.cs @@ -3,6 +3,7 @@ using System.Linq; using BeWo.Data.Access; using BeWo.Data.Entities; +using BeWo.Data.Security; using BeWo.Service.ServiceImplementations; using BS.Shared; using BS.Shared.Core; @@ -13,6 +14,8 @@ namespace BeWo.Service.DCEntityMapper { public class AiPromptbausteinRoutineDC_AiPromptbausteinRoutine : BeWoDataContract_BeWoEntityBase { + public Employee CurrentUser => UserRightHelper.GetLoggedInEmployee(); + public override AiPromptbausteinRoutineDC MergeWithDC(AiPromptbausteinRoutine pEntity, AiPromptbausteinRoutineDC pDataContract) { base.MergeWithDC(pEntity, pDataContract); @@ -22,9 +25,8 @@ namespace BeWo.Service.DCEntityMapper pDataContract.ParentFolderOid = pEntity.ParentFolderOid; pDataContract.IsPublic = pEntity.IsPublic; pDataContract.Position = pEntity.Position; - pDataContract.IsFavorite = pEntity.IsFavorite; + pDataContract.IsFavorite = pEntity.UserFavorites.Contains(CurrentUser); pDataContract.ActionType = pEntity.ActionType; - pDataContract.CanEdit = pEntity.CanEdit; pDataContract.Steps = MapperFactory.AiPromptbausteinRoutineStep.MapToNewDCs(pEntity.Steps); @@ -44,11 +46,22 @@ namespace BeWo.Service.DCEntityMapper pEntity.CreatorOid = pDataContract.Creator.EmployeeOid; pEntity.IsPublic = pDataContract.IsPublic; pEntity.Position = pDataContract.Position; - pEntity.IsFavorite = pDataContract.IsFavorite; pEntity.ActionType = pDataContract.ActionType; - pEntity.CanEdit = pDataContract.CanEdit; - pEntity.Steps = DAOFactory.GenericDAO.LoadByIDs(pDataContract.Steps.Select(x => x.Oid.Value)); + var user = CurrentUser; + if (pDataContract.IsFavorite && !pEntity.UserFavorites.Contains(user)) + { + pEntity.UserFavorites.Add(user); + } + else if (!pDataContract.IsFavorite && pEntity.UserFavorites.Contains(user)) + { + pEntity.UserFavorites.Remove(user); + } + + if (pEntity.Steps is null) + pEntity.Steps = new List(); + + MapperFactory.AiPromptbausteinRoutineStep.MergeWithEntitys(pDataContract.Steps, pEntity.Steps); if (pDataContract.ParentFolderOid is long oid && oid >= 0) pEntity.ParentFolderOid = pDataContract.ParentFolderOid; diff --git a/Service/Plugins/AiPromptbausteineService.cs b/Service/Plugins/AiPromptbausteineService.cs index 66fc0866f..c9243eeae 100644 --- a/Service/Plugins/AiPromptbausteineService.cs +++ b/Service/Plugins/AiPromptbausteineService.cs @@ -201,6 +201,11 @@ namespace BeWo.Service.Plugins prompt.CanEdit = true; } + foreach (var routine in folder.SubRoutines) + { + routine.CanEdit = true; + } + foreach (var next_folder in folder.SubFolders) { initOwnFolder(next_folder); diff --git a/Service/Service.csproj b/Service/Service.csproj index ce427e002..0ffcfe7a0 100644 --- a/Service/Service.csproj +++ b/Service/Service.csproj @@ -229,6 +229,10 @@ + + + + diff --git a/Service/ServiceContracts/Enhanced/IAiEnhancedService.cs b/Service/ServiceContracts/Enhanced/IAiEnhancedService.cs index 87ff5b096..6400d4687 100644 --- a/Service/ServiceContracts/Enhanced/IAiEnhancedService.cs +++ b/Service/ServiceContracts/Enhanced/IAiEnhancedService.cs @@ -80,47 +80,47 @@ namespace BeWo.Service.ServiceContracts.Enhanced [FaultContract(typeof(BeWoFault))] [OperationContract] [RequireWcfAuthorization(UserRightType.AiModulePromptbausteineEdit)] - IEnumerable InsertAiPromptbausteinFolder(IEnumerable folders); + AiPromptbausteinFolderDC InsertAiPromptbausteinFolder(AiPromptbausteinFolderDC folders); [FaultContract(typeof(BeWoFault))] [OperationContract] [RequireWcfAuthorization(UserRightType.AiModulePromptbausteineEdit)] - IEnumerable InsertAiPromptbausteinPrompt(IEnumerable prompts); - - [FaultContract(typeof(BeWoFault))] - [OperationContract] - [RequireWcfAuthorization(UserRightType.AiModulePromptbausteineEdit)] - IEnumerable InsertAiPromptbausteinRoutine(IEnumerable routine); + AiPromptbausteinPromptDC InsertAiPromptbausteinPrompt(AiPromptbausteinPromptDC prompts); [FaultContract(typeof(BeWoFault))] [OperationContract] [RequireWcfAuthorization(UserRightType.AiModulePromptbausteineEdit)] - IEnumerable UpdateAiPromptbausteinFolder(IEnumerable folders); + AiPromptbausteinRoutineDC InsertAiPromptbausteinRoutine(AiPromptbausteinRoutineDC routine); [FaultContract(typeof(BeWoFault))] [OperationContract] [RequireWcfAuthorization(UserRightType.AiModulePromptbausteineEdit)] - IEnumerable UpdateAiPromptbausteinPrompt(IEnumerable prompts); - - [FaultContract(typeof(BeWoFault))] - [OperationContract] - [RequireWcfAuthorization(UserRightType.AiModulePromptbausteineEdit)] - IEnumerable UpdateAiPromptbausteinRoutine(IEnumerable routine); + AiPromptbausteinFolderDC UpdateAiPromptbausteinFolder(AiPromptbausteinFolderDC folders); [FaultContract(typeof(BeWoFault))] [OperationContract] [RequireWcfAuthorization(UserRightType.AiModulePromptbausteineEdit)] - void DeleteAiPromptbausteinFolder(Dictionary oid2version); + AiPromptbausteinPromptDC UpdateAiPromptbausteinPrompt(AiPromptbausteinPromptDC prompts); [FaultContract(typeof(BeWoFault))] [OperationContract] [RequireWcfAuthorization(UserRightType.AiModulePromptbausteineEdit)] - void DeleteAiPromptbausteinPrompt(Dictionary oid2version); - + AiPromptbausteinRoutineDC UpdateAiPromptbausteinRoutine(AiPromptbausteinRoutineDC routine); + [FaultContract(typeof(BeWoFault))] [OperationContract] [RequireWcfAuthorization(UserRightType.AiModulePromptbausteineEdit)] - void DeleteAiPromptbausteinRoutine(Dictionary oid2version); + void DeleteAiPromptbausteinFolder(AiPromptbausteinFolderDC folder); + + [FaultContract(typeof(BeWoFault))] + [OperationContract] + [RequireWcfAuthorization(UserRightType.AiModulePromptbausteineEdit)] + void DeleteAiPromptbausteinPrompt(AiPromptbausteinPromptDC prompt); + + [FaultContract(typeof(BeWoFault))] + [OperationContract] + [RequireWcfAuthorization(UserRightType.AiModulePromptbausteineEdit)] + void DeleteAiPromptbausteinRoutine(AiPromptbausteinRoutineDC routine); [FaultContract(typeof(BeWoFault))] [OperationContract] diff --git a/Service/ServiceImplementations/Enhanced/AiEnhancedServiceImp.cs b/Service/ServiceImplementations/Enhanced/AiEnhancedServiceImp.cs index 312ac7221..958c643d0 100644 --- a/Service/ServiceImplementations/Enhanced/AiEnhancedServiceImp.cs +++ b/Service/ServiceImplementations/Enhanced/AiEnhancedServiceImp.cs @@ -1,6 +1,7 @@ using BeWo.Data.Access; using BeWo.Data.Entities; using BeWo.Data.Security; +using BeWo.Service.BusinessLogic; using BeWo.Service.Plugins; using BeWo.Service.ServiceContracts.Enhanced; using BS.Shared; @@ -66,33 +67,6 @@ namespace BeWo.Service.ServiceImplementations.Enhanced public IEnumerable GetAiPromptbausteinFolder(AiActionType aiActionType) => GetAiPromptbausteineService().GetAiPromptbausteinFolder(aiActionType); - public IEnumerable InsertAiPromptbausteinFolder(IEnumerable folders) - => GetAiPromptbausteineService().InsertAiPromptbausteinFolder(folders); - - public IEnumerable InsertAiPromptbausteinPrompt(IEnumerable prompts) - => GetAiPromptbausteineService().InsertAiPromptbausteinPrompt(prompts); - - public IEnumerable InsertAiPromptbausteinRoutine(IEnumerable routine) - => GetAiPromptbausteineService().InsertAiPromptbausteinRoutine(routine); - - public IEnumerable UpdateAiPromptbausteinFolder(IEnumerable folders) - => GetAiPromptbausteineService().UpdateAiPromptbausteinFolder(folders); - - public IEnumerable UpdateAiPromptbausteinPrompt(IEnumerable prompts) - => GetAiPromptbausteineService().UpdateAiPromptbausteinPrompt(prompts); - - public IEnumerable UpdateAiPromptbausteinRoutine(IEnumerable routine) - => GetAiPromptbausteineService().UpdateAiPromptbausteinRoutine(routine); - - public void DeleteAiPromptbausteinFolder(Dictionary oid2version) - => GetAiPromptbausteineService().DeleteAiPromptbausteinFolder(oid2version); - - public void DeleteAiPromptbausteinPrompt(Dictionary oid2version) - => GetAiPromptbausteineService().DeleteAiPromptbausteinPrompt(oid2version); - - public void DeleteAiPromptbausteinRoutine(Dictionary oid2version) - => GetAiPromptbausteineService().DeleteAiPromptbausteinRoutine(oid2version); - private AiPromptbausteineService GetAiPromptbausteineService() { return new AiPromptbausteineService(); @@ -100,6 +74,40 @@ namespace BeWo.Service.ServiceImplementations.Enhanced //var plugin = PluginLoader.FindClass(); //return plugin; } + + public AiPromptbausteinFolderDC InsertAiPromptbausteinFolder(AiPromptbausteinFolderDC folder) + => GetFolderLogic().Insert(folder); + + public AiPromptbausteinPromptDC InsertAiPromptbausteinPrompt(AiPromptbausteinPromptDC prompt) + => GetPromptLogic().Insert(prompt); + + public AiPromptbausteinRoutineDC InsertAiPromptbausteinRoutine(AiPromptbausteinRoutineDC routine) + => GetRoutineLogic().Insert(routine); + + public AiPromptbausteinFolderDC UpdateAiPromptbausteinFolder(AiPromptbausteinFolderDC folder) + => GetFolderLogic().Update(folder); + + public AiPromptbausteinPromptDC UpdateAiPromptbausteinPrompt(AiPromptbausteinPromptDC prompt) + => GetPromptLogic().Update(prompt); + + public AiPromptbausteinRoutineDC UpdateAiPromptbausteinRoutine(AiPromptbausteinRoutineDC routine) + => GetRoutineLogic().Update(routine); + + public void DeleteAiPromptbausteinFolder(AiPromptbausteinFolderDC folder) + => GetFolderLogic().Deactivate(folder); + + public void DeleteAiPromptbausteinPrompt(AiPromptbausteinPromptDC prompt) + => GetPromptLogic().Deactivate(prompt); + + public void DeleteAiPromptbausteinRoutine(AiPromptbausteinRoutineDC routine) + => GetRoutineLogic().Deactivate(routine); + + private AiPromptbausteinFolderLogic GetFolderLogic() + => new AiPromptbausteinFolderLogic(); + private AiPromptbausteinPromptLogic GetPromptLogic() + => new AiPromptbausteinPromptLogic(); + private AiPromptbausteinRoutineLogic GetRoutineLogic() + => new AiPromptbausteinRoutineLogic(); #endregion #region Functions From a5f6e00305fc858f6c1d432957d85480aefd4458 Mon Sep 17 00:00:00 2001 From: Rene Evertz Date: Fri, 15 May 2026 11:46:23 +0200 Subject: [PATCH 04/70] Hinweistext wenn kein Prompt enthalten --- BeWo/BeWo.csproj | 4 + .../CollectionCountToVisibilityConverter.cs | 8 +- BeWo/MainControl.xaml.cs | 2 +- BeWo/Styles/DataTemplates/DataTemplates.xaml | 1 + BeWo/Styles/Designs/GeometryCollection.xaml | 4 + BeWo/Styles/ModernOrangeBlack.xaml | 2 + .../AI/AiPromptbausteinComplexTreeView.xaml | 95 +++++++++++-------- Host/Host.csproj.user | 2 +- Service/Plugins/PluginLoader.cs | 1 + 9 files changed, 75 insertions(+), 44 deletions(-) create mode 100644 BeWo/Styles/Designs/GeometryCollection.xaml diff --git a/BeWo/BeWo.csproj b/BeWo/BeWo.csproj index a7539b52a..874ee2d4f 100644 --- a/BeWo/BeWo.csproj +++ b/BeWo/BeWo.csproj @@ -292,6 +292,10 @@ MSBuild:Compile Designer + + Designer + MSBuild:Compile + Designer MSBuild:Compile diff --git a/BeWo/Converter/CollectionCountToVisibilityConverter.cs b/BeWo/Converter/CollectionCountToVisibilityConverter.cs index 46a25386c..fbf96c071 100644 --- a/BeWo/Converter/CollectionCountToVisibilityConverter.cs +++ b/BeWo/Converter/CollectionCountToVisibilityConverter.cs @@ -12,7 +12,13 @@ namespace BeWo.Converter try { var count = (int)value; - return count > 0 ? Visibility.Visible : Visibility.Collapsed; + + if (parameter is string s && s == "reverse") + { + return count > 0 ? Visibility.Collapsed : Visibility.Visible; + } + + return count > 0 ? Visibility.Visible : Visibility.Collapsed; } catch (Exception) { diff --git a/BeWo/MainControl.xaml.cs b/BeWo/MainControl.xaml.cs index 305b70604..62539f6d8 100644 --- a/BeWo/MainControl.xaml.cs +++ b/BeWo/MainControl.xaml.cs @@ -176,7 +176,7 @@ namespace BeWo } - if (BeWoApp.LoggedOnUser != null && BeWoApp.LoggedOnUser.HasRight(UserRightType.DocumentsAllowViewAll) && BeWoApp.AppSettings.ShowVorlagen && (BeWoApp.LoggedOnUser.HasRight(UserRightType.VorlagenViewAll) || BeWoApp.LoggedOnUser.HasRight(UserRightType.VorlagenViewOwnTeams)) + if (BeWoApp.LoggedOnUser != null && BeWoApp.LoggedOnUser.HasRight(UserRightType.DocumentsAllowViewAll) && BeWoApp.AppSettings.ShowVorlagen && (BeWoApp.LoggedOnUser.HasRight(UserRightType.VorlagenViewAll) || BeWoApp.LoggedOnUser.HasRight(UserRightType.VorlagenViewOwnTeams))) { this.button_Dokumente.Visibility = Visibility.Visible; } diff --git a/BeWo/Styles/DataTemplates/DataTemplates.xaml b/BeWo/Styles/DataTemplates/DataTemplates.xaml index f39d699df..5c5e7b133 100644 --- a/BeWo/Styles/DataTemplates/DataTemplates.xaml +++ b/BeWo/Styles/DataTemplates/DataTemplates.xaml @@ -40,6 +40,7 @@ Cursor="Arrow" Focusable="False" FontWeight="{Binding FontWeight}" + FontSize="12" IsReadOnly="True" Text="{Binding Path=Title, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}" ToolTipService.ShowDuration="100000"> diff --git a/BeWo/Styles/Designs/GeometryCollection.xaml b/BeWo/Styles/Designs/GeometryCollection.xaml new file mode 100644 index 000000000..b79d50208 --- /dev/null +++ b/BeWo/Styles/Designs/GeometryCollection.xaml @@ -0,0 +1,4 @@ + + M238.25 957.4166666666666C182.4166666666667 952.4583333333334 136.6666666666667 909.9583333333334 126.8333333333333 853.9166666666667C124.0833333333333 838.125 124.0833333333333 161.8750000000001 126.8333333333333 146.0833333333334C135.8333333333333 94.6666666666666 174 55.1666666666667 225.4166666666667 44.0833333333334C235 42 252.125 41.875 500 41.875C747.875 41.875 764.9999999999999 42 774.5833333333333 44.0833333333334C826 55.1666666666667 864.1666666666665 94.6666666666666 873.1666666666666 146.0833333333334C876 162.25 875.9166666666665 673.1666666666667 873.0833333333333 689.4583333333333C868.9166666666666 713.3333333333334 858.7083333333334 736.2916666666667 844.125 754.625C839.875 760 799.6666666666666 801 754.75 845.7083333333334C670.1666666666666 930 666.5 933.3333333333334 646.4166666666666 943.2083333333334C630.0833333333333 951.25 616.7083333333333 955.2083333333334 598.125 957.4166666666666C584.9166666666666 958.9583333333334 256 959 238.25 957.4166666666666M541.5 784.0416666666667L541.875 693.125L545.375 682.875C552.3333333333333 662.2916666666667 569 643.0416666666667 588.0416666666666 633.6666666666667C605.625 625 605.1666666666666 625.0416666666667 703.4583333333333 625.0416666666667L791.2499999999999 625L791.2499999999999 391.9166666666668C791.2499999999999 159.875 791.2499999999999 158.8333333333335 788.6666666666666 152C785.2916666666666 142.9166666666668 776.6666666666666 133.5000000000001 767.7499999999999 129.1250000000001L760.6249999999999 125.6250000000001L500 125.6250000000001L239.375 125.6250000000001L232.25 129.1250000000001C223.3333333333334 133.5000000000001 214.7083333333333 142.9166666666668 211.3333333333333 152C208.75 158.8333333333335 208.75 158.9166666666668 208.75 500C208.75 839.9583333333334 208.75 841.1666666666667 211.2916666666667 847.9583333333334C215.9166666666667 860.375 228.25 871.2916666666667 240.1666666666667 873.6666666666666C243.1666666666667 874.25 312.125 874.7916666666666 393.375 874.875L541.125 875L541.5 784.0416666666667M700 783.125L774.375 708.75L699.6666666666667 708.75L625 708.75L625 783.125C625 824.0416666666667 625.125 857.5 625.3333333333333 857.5C625.5 857.5 659.0833333333333 824.0416666666667 700 783.125M488.75 540.1666666666667C477.7499999999999 536.5416666666667 467.5833333333333 527.9166666666667 462.3749999999999 517.75C459.375 511.8750000000001 459.375 511.7500000000001 459 464.125L458.6249999999999 416.375L410.875 416L363.125 415.625L356.875 412.3333333333334C349.0416666666667 408.1666666666667 341.2916666666667 400.4166666666667 337.375 392.75C334.8333333333333 387.75 334.375 385.0833333333334 334.375 375C334.375 364.9166666666667 334.8333333333333 362.2500000000001 337.4166666666667 357.2083333333334C341.25 349.625 349.625 341.25 357.2083333333333 337.4166666666668C363.125 334.375 363.1666666666667 334.375 410.875 334L458.6249999999999 333.625L459 285.8750000000001C459.375 238.1666666666668 459.375 238.125 462.4166666666667 232.2083333333334C466.2499999999999 224.625 474.625 216.2500000000001 482.2083333333333 212.4166666666666C487.25 209.8333333333335 489.9166666666666 209.375 500 209.375C510.0833333333333 209.375 512.7499999999999 209.8333333333335 517.7916666666666 212.4166666666666C525.375 216.2500000000001 533.75 224.625 537.5833333333333 232.2083333333334C540.625 238.125 540.625 238.1666666666668 541 285.8750000000001L541.375 333.625L589.1249999999999 334C636.8333333333334 334.375 636.875 334.375 642.7916666666666 337.4166666666668C650.375 341.25 658.75 349.625 662.5833333333333 357.2083333333334C665.1666666666666 362.2500000000001 665.625 364.9166666666667 665.625 375C665.625 385.0833333333334 665.1666666666666 387.75 662.625 392.75C658.7083333333333 400.4166666666667 650.9583333333333 408.1666666666667 643.125 412.3333333333334L636.875 415.625L589.1249999999999 416L541.375 416.375L541 464.125C540.625 511.7500000000001 540.625 511.8750000000001 537.625 517.75C533.6666666666666 525.4583333333334 525.9166666666666 533.2083333333334 518.125 537.2083333333334C513.25 539.7083333333333 509.6666666666666 540.5 501.8749999999999 540.7916666666667C496.375 541 490.4583333333333 540.7083333333334 488.75 540.1666666666667 + M213.66,82.34l-56-56A8,8,0,0,0,152,24H56A16,16,0,0,0,40,40V216a16,16,0,0,0,16,16H200a16,16,0,0,0,16-16V88A8,8,0,0,0,213.66,82.34ZM160,51.31,188.69,80H160ZM200,216H56V40h88V88a8,8,0,0,0,8,8h48V216Zm-40-64a8,8,0,0,1-8,8H136v16a8,8,0,0,1-16,0V160H104a8,8,0,0,1,0-16h16V128a8,8,0,0,1,16,0v16h16A8,8,0,0,1,160,152Z + \ No newline at end of file diff --git a/BeWo/Styles/ModernOrangeBlack.xaml b/BeWo/Styles/ModernOrangeBlack.xaml index 39d19217b..d92bdfd58 100644 --- a/BeWo/Styles/ModernOrangeBlack.xaml +++ b/BeWo/Styles/ModernOrangeBlack.xaml @@ -22,6 +22,8 @@ + + diff --git a/BeWo/View/Detail/AI/AiPromptbausteinComplexTreeView.xaml b/BeWo/View/Detail/AI/AiPromptbausteinComplexTreeView.xaml index 8e09dca56..1e8aedce1 100644 --- a/BeWo/View/Detail/AI/AiPromptbausteinComplexTreeView.xaml +++ b/BeWo/View/Detail/AI/AiPromptbausteinComplexTreeView.xaml @@ -518,47 +518,60 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Hier sind noch keine Prompts/Routinen angelegt. + + + + C:\Projects\Bewo\BeWo - Main\Host\Properties\PublishProfiles\FolderProfile.pubxml diff --git a/Service/Plugins/PluginLoader.cs b/Service/Plugins/PluginLoader.cs index 0a35c98fb..886b4892e 100644 --- a/Service/Plugins/PluginLoader.cs +++ b/Service/Plugins/PluginLoader.cs @@ -4,6 +4,7 @@ using System.IO; using System.Linq; using System.Reflection; using System.Threading; +using BeWo.Data; using BS.Shared.Core; namespace BeWo.Service.Plugins From f48e723875a37acdeb1ac7b4f94d8ff6d70e525a Mon Sep 17 00:00:00 2001 From: Rene Evertz Date: Fri, 15 May 2026 11:51:34 +0200 Subject: [PATCH 05/70] Routine Doppelklick --- .../AI/AiPromptbausteinComplexTreeView.xaml | 39 ++++++++++++++++--- .../AiPromptbausteinComplexTreeView.xaml.cs | 13 +++++++ 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/BeWo/View/Detail/AI/AiPromptbausteinComplexTreeView.xaml b/BeWo/View/Detail/AI/AiPromptbausteinComplexTreeView.xaml index 1e8aedce1..80b2f375f 100644 --- a/BeWo/View/Detail/AI/AiPromptbausteinComplexTreeView.xaml +++ b/BeWo/View/Detail/AI/AiPromptbausteinComplexTreeView.xaml @@ -220,7 +220,7 @@ Margin="6" Background="Transparent" ContextMenuOpening="ListBox_ContextMenuOpening" - PreviewMouseDown="Grid_PreviewMouseDown_1"> + PreviewMouseDown="Grid_PreviewMouseDown_2"> @@ -563,8 +563,9 @@ - @@ -574,7 +575,8 @@ - + + + + + + Hier sind noch keine Prompts angelegt. + + + - + - + + + + + + Hier sind noch keine Routinen angelegt. + + + diff --git a/BeWo/View/Detail/AI/AiPromptbausteinComplexTreeView.xaml.cs b/BeWo/View/Detail/AI/AiPromptbausteinComplexTreeView.xaml.cs index 8e3572ee5..64549b8f6 100644 --- a/BeWo/View/Detail/AI/AiPromptbausteinComplexTreeView.xaml.cs +++ b/BeWo/View/Detail/AI/AiPromptbausteinComplexTreeView.xaml.cs @@ -97,6 +97,7 @@ namespace BeWo.View.Detail.AI if (e.ClickCount == 2) { + ViewModel.OpenEditFolderDialogCommand.Execute(null); e.Handled = true; } @@ -145,5 +146,17 @@ namespace BeWo.View.Detail.AI listBoxEdit3.UnSelectAll(); } } + + private void Grid_PreviewMouseDown_2(object sender, MouseButtonEventArgs e) + { + if (!ViewModel.OpenEditRoutineDialogCommand.CanExecute(null)) + return; + + if (e.ClickCount == 2) + { + ViewModel.OpenEditRoutineDialogCommand.Execute(null); + e.Handled = true; + } + } } } From c1d9c3fa862473fd637f4fa05cca02802f628f91 Mon Sep 17 00:00:00 2001 From: Rene Evertz Date: Fri, 15 May 2026 12:11:44 +0200 Subject: [PATCH 06/70] UnselectAll --- BeWo/View/Detail/AI/AiPromptbausteinComplexTreeView.xaml.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BeWo/View/Detail/AI/AiPromptbausteinComplexTreeView.xaml.cs b/BeWo/View/Detail/AI/AiPromptbausteinComplexTreeView.xaml.cs index 64549b8f6..6d3167e07 100644 --- a/BeWo/View/Detail/AI/AiPromptbausteinComplexTreeView.xaml.cs +++ b/BeWo/View/Detail/AI/AiPromptbausteinComplexTreeView.xaml.cs @@ -141,8 +141,8 @@ namespace BeWo.View.Detail.AI { if(e.OriginalSource is TabControl) { - //listBoxEdit1.UnSelectAll(); - //listBoxEdit2.UnSelectAll(); + listBoxEdit1.UnSelectAll(); + listBoxEdit2.UnSelectAll(); listBoxEdit3.UnSelectAll(); } } From bc5f716f7d624fd1b9ab34c55d407cb9469f25b8 Mon Sep 17 00:00:00 2001 From: Rene Evertz Date: Fri, 15 May 2026 12:28:37 +0200 Subject: [PATCH 07/70] sauberer --- .../CollectionCountToBoolConverter.cs | 9 +- .../AI/AiPromptbausteinComplexTreeView.xaml | 27 ++++-- Service/Plugins/AiPromptbausteineService.cs | 91 +------------------ 3 files changed, 31 insertions(+), 96 deletions(-) diff --git a/BeWo/Converter/CollectionCountToBoolConverter.cs b/BeWo/Converter/CollectionCountToBoolConverter.cs index 9c164d3f2..bbee61a55 100644 --- a/BeWo/Converter/CollectionCountToBoolConverter.cs +++ b/BeWo/Converter/CollectionCountToBoolConverter.cs @@ -1,5 +1,6 @@ using System; using System.Globalization; +using System.Windows; using System.Windows.Data; namespace BeWo.Converter @@ -11,7 +12,13 @@ namespace BeWo.Converter try { var count = (int) value; - return count > 0; + + if (parameter is string s && s == "reverse") + { + return !(count > 0); + } + + return count > 0; } catch (Exception) { diff --git a/BeWo/View/Detail/AI/AiPromptbausteinComplexTreeView.xaml b/BeWo/View/Detail/AI/AiPromptbausteinComplexTreeView.xaml index 80b2f375f..e2353fbf5 100644 --- a/BeWo/View/Detail/AI/AiPromptbausteinComplexTreeView.xaml +++ b/BeWo/View/Detail/AI/AiPromptbausteinComplexTreeView.xaml @@ -563,8 +563,13 @@ + IsHitTestVisible="False"> + + + + + + @@ -615,8 +620,13 @@ + IsHitTestVisible="False"> + + + + + + @@ -661,8 +671,13 @@ +IsHitTestVisible="False"> + + + + + + diff --git a/Service/Plugins/AiPromptbausteineService.cs b/Service/Plugins/AiPromptbausteineService.cs index c9243eeae..c1850706a 100644 --- a/Service/Plugins/AiPromptbausteineService.cs +++ b/Service/Plugins/AiPromptbausteineService.cs @@ -41,93 +41,6 @@ namespace BeWo.Service.Plugins return result; } - public IEnumerable InsertAiPromptbausteinFolder(IEnumerable folders) - { - var entities = MapperFactory.AiPromptbausteinFolder.MapToNewEntities(folders); - - DAOFactory.GenericDAO.Insert(entities); - - return null; - } - public IEnumerable InsertAiPromptbausteinPrompt(IEnumerable prompts) - { - var entities = MapperFactory.AiPromptbausteinPrompt.MapToNewEntities(prompts); - - DAOFactory.GenericDAO.Insert(entities); - - return null; - } - public IEnumerable InsertAiPromptbausteinRoutine(IEnumerable routine) - { - var entities = MapperFactory.AiPromptbausteinRoutine.MapToNewEntities(routine); - - DAOFactory.GenericDAO.Insert(entities); - - return null; - } - public IEnumerable UpdateAiPromptbausteinFolder(IEnumerable folders) - { - var originale = DAOFactory.GenericDAO.LoadByIDs(folders.Select(sc => sc.Oid.Value)); - var folders2 = folders.ToList(); - MapperFactory.AiPromptbausteinFolder.MergeWithEntitys(folders2, originale); - - DAOFactory.GenericDAO.Update(originale); - - return null; - } - public IEnumerable UpdateAiPromptbausteinPrompt(IEnumerable prompts) - { - var originale = DAOFactory.GenericDAO.LoadByIDs(prompts.Select(sc => sc.Oid.Value)); - var prompts2 = prompts.ToList(); - MapperFactory.AiPromptbausteinPrompt.MergeWithEntitys(prompts2, originale); - - DAOFactory.GenericDAO.Update(originale); - - return null; - } - public IEnumerable UpdateAiPromptbausteinRoutine(IEnumerable routine) - { - var originale = DAOFactory.GenericDAO.LoadByIDs(routine.Select(sc => sc.Oid.Value)); - var routine2 = routine.ToList(); - MapperFactory.AiPromptbausteinRoutine.MergeWithEntitys(routine2, originale); - - DAOFactory.GenericDAO.Update(originale); - - return null; - } - - public void DeleteAiPromptbausteinFolder(Dictionary oid2version) - { - var originale = DAOFactory.GenericDAO.LoadByIDs(oid2version.Select(e => e.Key)); - originale.DoForEach(or => MapperFactory.AiPromptbausteinFolder.ConcurrencyCheck(oid2version[or.Oid.Value], or)); - - - DAOFactory.GenericDAO.SetActivationType(originale, BS.Shared.ActivationTypeId.Deleted); - } - private void delete_folder_rec(AiPromptbausteinFolder folder) - { - foreach (var sub_folder in folder.SubFolders) - { - delete_folder_rec(sub_folder); - } - - DAOFactory.GenericDAO.SetActivationType(folder, BS.Shared.ActivationTypeId.Deleted); - } - - public void DeleteAiPromptbausteinPrompt(Dictionary oid2version) - { - var originale = DAOFactory.GenericDAO.LoadByIDs(oid2version.Select(e => e.Key)); - originale.DoForEach(or => MapperFactory.AiPromptbausteinPrompt.ConcurrencyCheck(oid2version[or.Oid.Value], or)); - - DAOFactory.GenericDAO.SetActivationType(originale, BS.Shared.ActivationTypeId.Deleted); - } - public void DeleteAiPromptbausteinRoutine(Dictionary oid2version) - { - var originale = DAOFactory.GenericDAO.LoadByIDs(oid2version.Select(e => e.Key)); - originale.DoForEach(or => MapperFactory.AiPromptbausteinRoutine.ConcurrencyCheck(oid2version[or.Oid.Value], or)); - - DAOFactory.GenericDAO.SetActivationType(originale, BS.Shared.ActivationTypeId.Deleted); - } private AiPromptbausteinFolderDC getOwnFolder(AiActionType aiActionType) { @@ -155,8 +68,6 @@ namespace BeWo.Service.Plugins own_bib.SubPrompts.AddRange(own_prompts_dcs); - - var example_routine = new AiPromptbausteinRoutineDC(); example_routine.ActionType = aiActionType; example_routine.CanEdit = true; @@ -190,10 +101,12 @@ namespace BeWo.Service.Plugins return own_bib; } + private void initOwnFolder(AiPromptbausteinFolderDC folder) { folder.CanAddFolder = true; folder.CanAddPrompt = true; + folder.CanAddRoutine = true; folder.CanEdit = true; foreach (var prompt in folder.SubPrompts) From 2d8e7d1e65020bacff803cd945a797c397f5a813 Mon Sep 17 00:00:00 2001 From: Rene Evertz Date: Mon, 18 May 2026 12:03:10 +0200 Subject: [PATCH 08/70] Routine + Item Accepted --- .../Controls/AI/AiConversationButton.xaml.cs | 6 +- .../AI/AiPromptbausteinButton.xaml.cs | 6 +- ...steinComplexSelectionFavoritenView.xaml.cs | 2 +- .../AiPromptbausteinComplexSelectionView.xaml | 789 +++++++++++++----- ...PromptbausteinComplexSelectionView.xaml.cs | 137 ++- .../AI/AiPromptbausteinComplexTreeView.xaml | 200 ++--- .../AI/AiPromptbausteinRoutineView.xaml.cs | 15 +- .../Zeiterfassung/ServiceRecordEditView.xaml | 2 +- .../ServiceRecordEditView.xaml.cs | 5 +- .../Zeiterfassung/ServiceRecordView2.xaml | 4 +- .../Zeiterfassung/ServiceRecordView2.xaml.cs | 9 +- BeWo/ViewModel/AiPromptbausteinFolderVM.cs | 12 - BeWo/ViewModel/AiPromptbausteinPromptVM.cs | 7 - .../ListViewModel/ServiceRecordListVM.cs | 15 +- ...PromptbausteinComplexSelectionViewModel.cs | 245 ++++-- .../AiPromptbausteinComplexTreeViewModel.cs | 12 +- Dakota/Logic/DakotaKTDReader.cs | 2 + Data/Access/SearchDAO.cs | 19 + Service/Plugins/AiPromptbausteineService.cs | 34 +- .../Feature/AI/AiPromptbausteinFolderDC.cs | 1 + .../.cr/personal/FavoritesList/List.xml | 6 + 21 files changed, 1085 insertions(+), 443 deletions(-) create mode 100644 Tools/KTDReaderGUI/.cr/personal/FavoritesList/List.xml diff --git a/BeWo/View/Controls/AI/AiConversationButton.xaml.cs b/BeWo/View/Controls/AI/AiConversationButton.xaml.cs index 897933012..7c5716419 100644 --- a/BeWo/View/Controls/AI/AiConversationButton.xaml.cs +++ b/BeWo/View/Controls/AI/AiConversationButton.xaml.cs @@ -48,7 +48,7 @@ namespace BeWo.View.Controls.AI public event RoutedEventHandler OpenAiWindowClick; - public event EventHandler PromptAccepted; + public event EventHandler ItemAccepted; public AiConversationButton() { @@ -176,12 +176,12 @@ namespace BeWo.View.Controls.AI VMFactory.CreateAiPromptbausteinFolderListVM(folders, (listvm) => { var viewmodel = new AiPromptbausteinSelectionComplexViewModel(actionType, listvm); - viewmodel.PromptAccepted += PromptAccepted; + viewmodel.ItemAccepted += ItemAccepted; viewmodel.RequestClose += (s, e) => viewmodel.ResetSelection(); AllPromptsViewModel = viewmodel; var viewmodel2 = new AiPromptbausteinSelectionComplexViewModel(actionType, listvm, true); - viewmodel2.PromptAccepted += PromptAccepted; + viewmodel2.ItemAccepted += ItemAccepted; popup_promptbaustein_favoriten.Closed += (s, e) => viewmodel2.ResetSelection(); var view2 = new AiPromptbausteinComplexSelectionFavoritenView(viewmodel2); viewmodel2.SelectedFolder = viewmodel2.Folders.VMList[0]; diff --git a/BeWo/View/Controls/AI/AiPromptbausteinButton.xaml.cs b/BeWo/View/Controls/AI/AiPromptbausteinButton.xaml.cs index c91d88dd4..371852031 100644 --- a/BeWo/View/Controls/AI/AiPromptbausteinButton.xaml.cs +++ b/BeWo/View/Controls/AI/AiPromptbausteinButton.xaml.cs @@ -46,7 +46,7 @@ namespace BeWo.View.Controls.AI public static readonly DependencyProperty ActionTypeProperty = DependencyProperty.Register("ActionType", typeof(AiActionType), typeof(AiPromptbausteinButton), new PropertyMetadata(AiActionType.ServiceRecord, OnActionTypeChanged)); - public event EventHandler PromptAccepted; + public event EventHandler ItemAccepted; public AiPromptbausteinSelectionComplexViewModel AllPromptsViewModel { get; set; } @@ -114,12 +114,12 @@ namespace BeWo.View.Controls.AI VMFactory.CreateAiPromptbausteinFolderListVM(folders, (listvm) => { var viewmodel = new AiPromptbausteinSelectionComplexViewModel(actionType, listvm); - viewmodel.PromptAccepted += PromptAccepted; + viewmodel.ItemAccepted += ItemAccepted; viewmodel.RequestClose += (s, e) => viewmodel.ResetSelection(); AllPromptsViewModel = viewmodel; var viewmodel2 = new AiPromptbausteinSelectionComplexViewModel(actionType, listvm, true); - viewmodel2.PromptAccepted += PromptAccepted; + viewmodel2.ItemAccepted += ItemAccepted; popup_promptbaustein_favoriten.Closed += (s, e) => viewmodel2.ResetSelection(); var view2 = new AiPromptbausteinComplexSelectionFavoritenView(viewmodel2); viewmodel2.SelectedFolder = viewmodel2.Folders.VMList[0]; diff --git a/BeWo/View/Detail/AI/AiPromptbausteinComplexSelectionFavoritenView.xaml.cs b/BeWo/View/Detail/AI/AiPromptbausteinComplexSelectionFavoritenView.xaml.cs index b5ffdf6ef..770622cda 100644 --- a/BeWo/View/Detail/AI/AiPromptbausteinComplexSelectionFavoritenView.xaml.cs +++ b/BeWo/View/Detail/AI/AiPromptbausteinComplexSelectionFavoritenView.xaml.cs @@ -66,7 +66,7 @@ namespace BeWo.View.Detail.AI if (vm is null) return; - ViewModel.SelectedPrompt = vm; + ViewModel.SelectedItem = vm; } } } diff --git a/BeWo/View/Detail/AI/AiPromptbausteinComplexSelectionView.xaml b/BeWo/View/Detail/AI/AiPromptbausteinComplexSelectionView.xaml index 011631be4..cc05344e4 100644 --- a/BeWo/View/Detail/AI/AiPromptbausteinComplexSelectionView.xaml +++ b/BeWo/View/Detail/AI/AiPromptbausteinComplexSelectionView.xaml @@ -8,6 +8,7 @@ xmlns:local="clr-namespace:BeWo.View.Detail.AI" xmlns:local1="clr-namespace:BeWo.View.Detail.AI" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:templateselectors="clr-namespace:BeWo.View.TemplateSelectors" xmlns:vm="clr-namespace:BeWo.ViewModel" d:DataContext="{d:DesignInstance Type=ai:AiPromptbausteinSelectionComplexViewModel, IsDesignTimeCreatable=True}" @@ -23,9 +24,342 @@ + TargetType="ListBoxItem" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + (i) + + + + + + + + + Bearbeitet vor x Minuten + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -44,27 +378,31 @@ + @@ -94,6 +432,17 @@ + + + + + + + + + + + @@ -104,203 +453,253 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (i) - - - - - - - + Padding="0" + BorderBrush="Gray" + BorderThickness="0,1,1,1" + SelectionChanged="TabControl_SelectionChanged"> + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Hier sind noch keine Prompts angelegt. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Hier sind noch keine Routinen angelegt. + + + + + +