This commit is contained in:
2025-10-22 10:47:23 +02:00
parent 9d08c20e99
commit 61e4e3fff3
4 changed files with 203 additions and 80 deletions

View File

@@ -110,7 +110,7 @@
<Compile Include="ViewModel\AddressVM.cs" />
<Compile Include="ViewModel\AiConfigVM.cs" />
<Compile Include="ViewModel\ListViewModel\AiPromptbausteinListVM.cs" />
<Compile Include="ViewModel\TextModuleListVM.cs" />
<Compile Include="ViewModel\ListViewModel\TextModuleListVM.cs" />
<Compile Include="ViewModel\AiPromptbausteinVM.cs" />
<Compile Include="ViewModel\View\AiConversationChatViewModel.cs" />
<Compile Include="ViewModel\View\WindowViewModel.cs" />

View File

@@ -1,39 +1,49 @@
<view:BeWoView x:Class="BeWo.View.Detail.AiPromptbausteinView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:view="clr-namespace:BeWo.View"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
xmlns:detail="clr-namespace:BeWo.View.Detail"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
Height="Auto" Width="Auto" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" Focusable="True">
<view:BeWoView.Resources>
<detail:IsOnlyForEmployeeRightsConverter x:Key="IsOnlyForEmployeeRightsConverter" />
<detail:AiPromptbausteinEditConverter x:Key="AiPromptbausteinEditConverter" />
<view:BeWoView
x:Class="BeWo.View.Detail.AiPromptbausteinView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:detail="clr-namespace:BeWo.View.Detail"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
xmlns:view="clr-namespace:BeWo.View"
Width="Auto"
Height="Auto"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Focusable="True">
<view:BeWoView.Resources>
<detail:IsOnlyForEmployeeRightsConverter2 x:Key="IsOnlyForEmployeeRightsConverter2" />
<detail:AiPromptbausteinEditConverter x:Key="AiPromptbausteinEditConverter" />
</view:BeWoView.Resources>
<GroupBox Name="root" Header="Aktuell definierte KI-Prompts" Style="{StaticResource ObjectEditGroupBox}">
<Grid VerticalAlignment="Stretch">
<GroupBox
Name="root"
Header="Aktuell definierte KI-Prompts"
Style="{StaticResource ObjectEditGroupBox}">
<Grid VerticalAlignment="Stretch">
<Grid.Resources>
<ContextMenu x:Key="ContextMenuAiPromptbausteine" MenuItem.Click="ContextMenuAiPromptbausteine_Click" Opened="ContextMenuAiPromptbausteine_Opened">
<ContextMenu
x:Key="ContextMenuAiPromptbausteine"
MenuItem.Click="ContextMenuAiPromptbausteine_Click"
Opened="ContextMenuAiPromptbausteine_Opened">
<MenuItem Header="Neue KI Prompt-Kategorie">
<MenuItem.Icon>
<Image Source="..\..\Ressources\Icons\Add24.png"/>
<Image Source="..\..\Ressources\Icons\Add24.png" />
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Neuer KI-Prompt">
<MenuItem.Icon>
<Image Source="..\..\Ressources\Icons\Add24.png"/>
<Image Source="..\..\Ressources\Icons\Add24.png" />
</MenuItem.Icon>
</MenuItem>
</ContextMenu>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
@@ -42,29 +52,86 @@
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Label Grid.Column="0" Grid.Row="0" Content="Name" />
<TextBox Grid.Column="1" Grid.Row="0" Text="{Binding Path=NewVM.Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="150" />
<Label Grid.Column="2" Grid.Row="0" Content="Text" />
<TextBox Grid.Column="3" Grid.Row="0" Grid.RowSpan="2" AcceptsReturn="True" VerticalScrollBarVisibility="Auto" Text="{Binding Path=NewVM.Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsEnabled="{Binding Path=NewVM.IsParent, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource BoolReverseConverter}}" />
<Label Grid.Column="0" Grid.Row="1" Content="KI Prompt-Kategorie" />
<dxe:ComboBoxEdit Grid.Column="1" Grid.Row="1" Margin="3" Height="23" Width="150" EditMode="Standalone"
ItemsSource="{Binding Path=PossibleAiPromptbausteinParents}"
SelectedItem="{Binding Path=NewVM.Parent}">
<dxe:ComboBoxEdit.Buttons>
<dxe:ButtonInfo GlyphKind="Cancel" Click="RemoveParentAiPromptbausteinFromNewVM_OnClick" />
</dxe:ComboBoxEdit.Buttons>
</dxe:ComboBoxEdit>
<CheckBox Grid.Column="0" Grid.Row="2" Content="Ist AiPromptbausteinkategorie" Margin="3" IsChecked="{Binding Path=NewVM.IsParent, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Checked="IsAiPromptbausteinParent_Checked" />
<Button Grid.Column="0" Grid.Row="3" Grid.ColumnSpan="4" HorizontalAlignment="Right" Content="Hinzufügen" Margin="3,3,0,3" Click="AddAiPromptbausteinButton_Click" />
<dxg:TreeListControl Name="TreeListControl" Grid.Column="0" Grid.ColumnSpan="3" Grid.Row="4" dx:ThemeManager.ThemeName="Office2010Black" ItemsSource="{Binding Path=VMList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Margin="0" ContextMenu="{StaticResource ContextMenuAiPromptbausteine}"
ItemsSourceChanged="TreeListControl_ItemsSourceChanged"
PreviewMouseDown="TreeListControl_OnPreviewMouseDown">
<Label
Grid.Row="0"
Grid.Column="0"
Content="Name" />
<TextBox
Grid.Row="0"
Grid.Column="1"
Width="150"
Text="{Binding Path=NewVM.Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<Label
Grid.Row="0"
Grid.Column="2"
Content="Text" />
<TextBox
Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="3"
AcceptsReturn="True"
IsEnabled="{Binding Path=NewVM.IsParent, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource BoolReverseConverter}}"
Text="{Binding Path=NewVM.Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
VerticalScrollBarVisibility="Auto" />
<Label
Grid.Row="1"
Grid.Column="0"
Content="KI Prompt-Kategorie" />
<dxe:ComboBoxEdit
Grid.Row="1"
Grid.Column="1"
Width="150"
Height="23"
Margin="3"
EditMode="Standalone"
ItemsSource="{Binding Path=PossibleAiPromptbausteinParents}"
SelectedItem="{Binding Path=NewVM.Parent}">
<dxe:ComboBoxEdit.Buttons>
<dxe:ButtonInfo Click="RemoveParentAiPromptbausteinFromNewVM_OnClick" GlyphKind="Cancel" />
</dxe:ComboBoxEdit.Buttons>
</dxe:ComboBoxEdit>
<CheckBox
Grid.Row="2"
Grid.Column="0"
Margin="3"
Checked="IsAiPromptbausteinParent_Checked"
Content="Ist AiPromptbausteinkategorie"
IsChecked="{Binding Path=NewVM.IsParent, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<Button
Grid.Row="3"
Grid.Column="0"
Grid.ColumnSpan="4"
Margin="3,3,0,3"
HorizontalAlignment="Right"
Click="AddAiPromptbausteinButton_Click"
Content="Hinzufügen" />
<dxg:TreeListControl
Name="TreeListControl"
Grid.Row="4"
Grid.Column="0"
Grid.ColumnSpan="3"
Margin="0"
dx:ThemeManager.ThemeName="Office2010Black"
ContextMenu="{StaticResource ContextMenuAiPromptbausteine}"
ItemsSource="{Binding Path=VMList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ItemsSourceChanged="TreeListControl_ItemsSourceChanged"
PreviewMouseDown="TreeListControl_OnPreviewMouseDown">
<dxg:TreeListControl.Columns>
<dxg:TreeListColumn FieldName="IsDeleteable" FixedWidth="True" Width="24" ReadOnly="True" Header=" ">
<dxg:TreeListColumn
Width="24"
FieldName="IsDeleteable"
FixedWidth="True"
Header=" "
ReadOnly="True">
<dxg:TreeListColumn.CellTemplate>
<DataTemplate>
<Button Content="r" Click="DeleteButton_Click" FontFamily="Webdings" Width="18" Height="18" VerticalAlignment="Center">
<Button
Width="18"
Height="18"
VerticalAlignment="Center"
Click="DeleteButton_Click"
Content="r"
FontFamily="Webdings">
<Button.IsEnabled>
<MultiBinding Converter="{StaticResource AiPromptbausteinEditConverter}">
<Binding />
@@ -78,7 +145,10 @@
<dxg:TreeListColumn FieldName="Name">
<dxg:TreeListColumn.DisplayTemplate>
<ControlTemplate>
<dxe:TextEdit EditMode="InplaceInactive" FontWeight="{Binding Path=DataContext.RowData.Row.FontWeight, RelativeSource={RelativeSource TemplatedParent}}" Text="{Binding Path=DataContext.RowData.Row.Name, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}, UpdateSourceTrigger=PropertyChanged}">
<dxe:TextEdit
EditMode="InplaceInactive"
FontWeight="{Binding Path=DataContext.RowData.Row.FontWeight, RelativeSource={RelativeSource TemplatedParent}}"
Text="{Binding Path=DataContext.RowData.Row.Name, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}, UpdateSourceTrigger=PropertyChanged}">
<dxe:TextEdit.IsEnabled>
<MultiBinding Converter="{StaticResource AiPromptbausteinEditConverter}">
<Binding />
@@ -90,7 +160,11 @@
</dxg:TreeListColumn.DisplayTemplate>
<dxg:TreeListColumn.EditTemplate>
<ControlTemplate>
<dxe:TextEdit x:Name="PART_Editor" EditMode="InplaceActive" FontWeight="{Binding Path=DataContext.RowData.Row.FontWeight, RelativeSource={RelativeSource TemplatedParent}}" Text="{Binding Path=DataContext.RowData.Row.Name, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}, UpdateSourceTrigger=PropertyChanged}">
<dxe:TextEdit
x:Name="PART_Editor"
EditMode="InplaceActive"
FontWeight="{Binding Path=DataContext.RowData.Row.FontWeight, RelativeSource={RelativeSource TemplatedParent}}"
Text="{Binding Path=DataContext.RowData.Row.Name, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}, UpdateSourceTrigger=PropertyChanged}">
<dxe:TextEdit.IsEnabled>
<MultiBinding Converter="{StaticResource AiPromptbausteinEditConverter}">
<Binding />
@@ -104,36 +178,56 @@
<dxg:TreeListColumn FieldName="Text">
<dxg:TreeListColumn.CellTemplate>
<DataTemplate>
<dxe:TextEdit x:Name="PART_Editor" EditMode="InplaceActive" Text="{Binding Path=DataContext.RowData.Row.Text, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}, UpdateSourceTrigger=PropertyChanged}"
IsEnabled="{Binding Path=DataContext.RowData.Row, Converter={StaticResource IsOnlyForEmployeeRightsConverter}, RelativeSource={RelativeSource TemplatedParent}}" AcceptsReturn="True" AcceptsTab="True" TextTrimming="WordEllipsis" TextWrapping="Wrap" SelectAllOnGotFocus="False" SelectAllOnMouseUp="False" />
<dxe:TextEdit
x:Name="PART_Editor"
AcceptsReturn="True"
AcceptsTab="True"
EditMode="InplaceActive"
IsEnabled="{Binding Path=DataContext.RowData.Row, Converter={StaticResource IsOnlyForEmployeeRightsConverter}, RelativeSource={RelativeSource TemplatedParent}}"
SelectAllOnGotFocus="False"
SelectAllOnMouseUp="False"
Text="{Binding Path=DataContext.RowData.Row.Text, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}, UpdateSourceTrigger=PropertyChanged}"
TextTrimming="WordEllipsis"
TextWrapping="Wrap" />
</DataTemplate>
</dxg:TreeListColumn.CellTemplate>
</dxg:TreeListColumn>
<dxg:TreeListColumn FieldName="Parent" Header="KI Prompt-Kategorie">
<dxg:TreeListColumn.DisplayTemplate>
<ControlTemplate>
<dxe:ComboBoxEdit EditMode="InplaceActive" IsTextEditable="False"
ItemsSource="{Binding Path=DataContext.PossibleAiPromptbausteinParents, RelativeSource={RelativeSource FindAncestor, AncestorType=dxg:TreeListControl}}"
SelectedItem="{Binding Path=DataContext.RowData.Row.Parent, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
Tag="{Binding Path=DataContext.RowData.Row, RelativeSource={RelativeSource TemplatedParent}}"
Loaded="FrameworkElement_OnLoaded">
<dxe:ComboBoxEdit
EditMode="InplaceActive"
IsTextEditable="False"
ItemsSource="{Binding Path=DataContext.PossibleAiPromptbausteinParents, RelativeSource={RelativeSource FindAncestor, AncestorType=dxg:TreeListControl}}"
Loaded="FrameworkElement_OnLoaded"
SelectedItem="{Binding Path=DataContext.RowData.Row.Parent, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
Tag="{Binding Path=DataContext.RowData.Row, RelativeSource={RelativeSource TemplatedParent}}">
<dxe:ComboBoxEdit.Buttons>
<dxe:ButtonInfo GlyphKind="Cancel" Click="ButtonInfo_OnClick" Tag="{Binding}" />
<dxe:ButtonInfo
Click="ButtonInfo_OnClick"
GlyphKind="Cancel"
Tag="{Binding}" />
</dxe:ComboBoxEdit.Buttons>
</dxe:ComboBoxEdit>
</ControlTemplate>
</dxg:TreeListColumn.DisplayTemplate>
<dxg:TreeListColumn.EditTemplate>
<ControlTemplate>
<!-- KI Prompt-Kategorie -->
<dxe:ComboBoxEdit x:Name="PART_Editor" EditMode="InplaceActive" IsTextEditable="False"
ItemsSource="{Binding Path=DataContext.PossibleAiPromptbausteinParents, RelativeSource={RelativeSource FindAncestor, AncestorType=dxg:TreeListControl}}"
SelectedItem="{Binding Path=DataContext.RowData.Row.Parent, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
EditValueChanged="PART_Editor_OnEditValueChanged"
Tag="{Binding Path=DataContext.RowData.Row, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
Loaded="FrameworkElement_OnLoaded">
<!-- KI Prompt-Kategorie -->
<dxe:ComboBoxEdit
x:Name="PART_Editor"
EditMode="InplaceActive"
EditValueChanged="PART_Editor_OnEditValueChanged"
IsTextEditable="False"
ItemsSource="{Binding Path=DataContext.PossibleAiPromptbausteinParents, RelativeSource={RelativeSource FindAncestor, AncestorType=dxg:TreeListControl}}"
Loaded="FrameworkElement_OnLoaded"
SelectedItem="{Binding Path=DataContext.RowData.Row.Parent, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
Tag="{Binding Path=DataContext.RowData.Row, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}">
<dxe:ComboBoxEdit.Buttons>
<dxe:ButtonInfo GlyphKind="Cancel" Click="ButtonInfo_OnClick" Tag="{Binding}" />
<dxe:ButtonInfo
Click="ButtonInfo_OnClick"
GlyphKind="Cancel"
Tag="{Binding}" />
</dxe:ComboBoxEdit.Buttons>
</dxe:ComboBoxEdit>
</ControlTemplate>
@@ -141,11 +235,14 @@
</dxg:TreeListColumn>
</dxg:TreeListControl.Columns>
<dxg:TreeListControl.View>
<dxg:TreeListView Name="TreeListView" AutoWidth="True" KeyFieldName="KeyField" ParentFieldName="ParentField"
ExpandStateBinding="{Binding Path=IsExpanded, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
/>
<dxg:TreeListView
Name="TreeListView"
AutoWidth="True"
ExpandStateBinding="{Binding Path=IsExpanded, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
KeyFieldName="KeyField"
ParentFieldName="ParentField" />
</dxg:TreeListControl.View>
</dxg:TreeListControl>
</Grid>
</GroupBox>
</GroupBox>
</view:BeWoView>

View File

@@ -63,17 +63,17 @@ namespace BeWo.View.Detail
if (ViewModel.AddedCount > 0)
{
lToDos.Add(s => s.InsertNewAiPromptbausteine(ViewModel.CommitAdded()));
//lToDos.Add(s => s.InsertNewAiPromptbausteine(ViewModel.CommitAdded()));
}
if (ViewModel.RemovedCount > 0)
{
lToDos.Add(s => s.DeleteAiPromptbausteine(ViewModel.GetRemoved().ToDictionary(dc => dc.Oid.Value, dc => dc.Version.Value)));
//lToDos.Add(s => s.DeleteAiPromptbausteine(ViewModel.GetRemoved().ToDictionary(dc => dc.Oid.Value, dc => dc.Version.Value)));
}
if (ViewModel.ChangedCount > 0)
{
lToDos.Add(s => s.UpdateAiPromptbausteine(ViewModel.CommitChanged()));
//lToDos.Add(s => s.UpdateAiPromptbausteine(ViewModel.CommitChanged()));
}
ServiceFacade.DoMultipleOperationsServicesAsync(lToDos, () =>
@@ -85,17 +85,17 @@ namespace BeWo.View.Detail
private void ReloadViewModel()
{
VMFactory.CreateAiPromptbausteinListVMAsync(r => this.Dispatch(delegate
{
TreeListControl.BeginDataUpdate();
//VMFactory.CreateAiPromptbausteinListVMAsync(r => this.Dispatch(delegate
//{
// TreeListControl.BeginDataUpdate();
ViewModel = r;
// ViewModel = r;
TreeListControl.EndDataUpdate();
// TreeListControl.EndDataUpdate();
TreeListControl.SelectedItems.Clear();
// TreeListControl.SelectedItems.Clear();
}), _IsInAdministrationView);
//}), _IsInAdministrationView);
}
private void DeleteButton_Click(object sender, RoutedEventArgs e)
@@ -285,9 +285,19 @@ namespace BeWo.View.Detail
ViewModel.AddNewVMToList(false);
Save();
}
}
public class IsOnlyForEmployeeRightsConverter2 : IValueConverter
private void ContextMenuAiPromptbausteine_Click(object sender, RoutedEventArgs e)
{
}
private void ContextMenuAiPromptbausteine_Opened(object sender, RoutedEventArgs e)
{
}
}
public class IsOnlyForEmployeeRightsConverter2 : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
@@ -301,4 +311,21 @@ namespace BeWo.View.Detail
throw new NotImplementedException();
}
}
public class AiPromptbausteinEditConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var fieldname = ((EditGridCellData)values[0]).Column.FieldName;
var shuoldBeEditableDespiteBeingFromAParentElement = fieldname.Equals("Name") || fieldname.Equals("IsDeleteable");
var textModule = (AiPromptbausteinVM)values[1];
return AiPromptbausteinView.CheckEditorRights(textModule, parameter) && shuoldBeEditableDespiteBeingFromAParentElement;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

View File

@@ -231,7 +231,6 @@ namespace BeWo.ViewModel
return
Equals(IsNew, obj.IsNew) &&
Equals(ServiceCategory, obj.ServiceCategory) &&
Equals(Text, obj.Text) &&
Equals(Position, obj.Position) &&
Equals(Parent, obj.Parent) &&