Эх сурвалжийг харах

working search panel with basic functionality

Dalibor Votruba 2 жил өмнө
parent
commit
1dde01aa81

+ 38 - 0
Workbench/QMonitor/qmonlib.ui/Models/General/CheckBoxListItem.cs

@@ -0,0 +1,38 @@
+using ReactiveUI;
+
+namespace qmonlib.ui.Models.General
+{
+    public class CheckBoxListItem : ReactiveObject
+    {
+        #region *** Private Fields ***
+        private bool _isChecked;
+        private string _name;
+        private string _identity;
+        #endregion
+
+        public string Identity
+        {
+            get => _identity;
+            set => this.RaiseAndSetIfChanged(ref _identity, value);
+        }
+        public string Name
+        {
+            get=>_name; 
+            set=>this.RaiseAndSetIfChanged(ref _name, value);
+        }
+
+        public bool IsChecked
+        {
+            get => _isChecked;
+            set => this.RaiseAndSetIfChanged(ref _isChecked, value);
+        }
+        
+        public CheckBoxListItem(string identity, string name, bool isChecked = false)
+        {
+            Identity = identity;
+            Name = name;
+            IsChecked = isChecked;
+        }
+        public CheckBoxListItem(string name) : this(string.Empty, name) { }
+    }
+}

+ 123 - 5
Workbench/QMonitor/qmonlib.ui/ViewModels/Navigator/NavSearchViewModel.cs

@@ -1,25 +1,143 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Diagnostics;
+using System.Linq;
+using System.Reactive.Linq;
+using qmonlib.ui.Models.General;
 using Quadarax.Foundation.Core.QMonitor;
+using Quadarax.Foundation.Core.Value;
+using ReactiveUI;
 
 namespace qmonlib.ui.ViewModels.Navigator
 {
     public class NavSearchViewModel : ReceiverViewModelBase
     {
+
+        #region *** Private Fields ***
+        private readonly ObservableCollection<MonGeneral> _allData;
+        private readonly ConcurrentDictionary<string,CheckBoxListItem> _instancesCache = new ConcurrentDictionary<string, CheckBoxListItem>();
+        private readonly IEqualityComparer<string> _eq = new StringPatternComparer();
+        private string? _searchText;
+        #endregion
+
         /// <summary>
         /// Filter pattern expression
         /// </summary>
-        public string? SearchText { get; set; }
+        public string? SearchText
+        {
+            get => _searchText;
+            set => this.RaiseAndSetIfChanged(ref _searchText, value);
+        }
+
         /// <summary>
         /// List of general metadata (filtered by <see cref="SearchText"/>)
         /// </summary>
-        public IList<MonGeneral> DataFiltered { get; set; } = new List<MonGeneral>();
+        public ObservableCollection<MonItemGeneral> DataFiltered
+        {
+            get
+            {
+                var instances = DataInstances;
+                var dataInstances = _allData.Where(x =>
+                    instances.Any(y =>
+                        string.Equals(y.Name, x.InstanceIdentifier, StringComparison.InvariantCultureIgnoreCase) &&
+                        y.IsChecked));
+                Debug.WriteLine($"*DataFiltered.dataInstances cnt = {dataInstances.Count()}");
+                var result = new ObservableCollection<MonItemGeneral>(
+                    dataInstances.SelectMany(x => x.Items).Where(x => _eq.Equals(x.Name, SearchText))
+                );
+                Debug.WriteLine($"*DataFiltered cnt = {result.Count}");
+                return result;
+            } 
+            set => throw new NotSupportedException();
+        }
+
+        /// <summary>
+        /// List of general metadata source instances
+        /// </summary>
+        public ObservableCollection<CheckBoxListItem> DataInstances
+        {
+            get
+            {
+                var newInstances = _allData.Select(x => x.InstanceIdentifier).Distinct().Select(x => new CheckBoxListItem(x));
+                foreach (var newInstance in newInstances)
+                {
+                    if (_instancesCache.ContainsKey(newInstance.Name))
+                        continue;
+                    
+                    _instancesCache.TryAdd(newInstance.Name, newInstance);
+                }
+
+                return new ObservableCollection<CheckBoxListItem>(_instancesCache.Select(x=>x.Value));
+            }
+            set => throw new NotSupportedException();
+        }
+        public int DataInstancesCount
+        {
+            get => DataInstances.Count;
+            set => throw new NotSupportedException();
+        }
+
+        public int DataInstancesSelectedCount
+        {
+            get => DataInstances.Count(x => x.IsChecked);
+            set => throw new NotSupportedException();
+        }
+
         /// <summary>
         /// Count of general metadata total count (not filtered)
         /// </summary>
-        public int DataTotalCount { get; set; }
+        public int DataTotalCount
+        {
+            get => _allData.SelectMany(x=>x.Items).Count(); 
+            set => throw new NotSupportedException();
+        }
         /// <summary>
         /// Count of general metadata filtered count (what returns in <see cref="DataFiltered"/>
         /// </summary>
-        public int DataFilteredCount { get; set; }
+        public int DataFilteredCount
+        {
+            get => DataFiltered.Count;
+            set => throw new NotSupportedException();
+        }
+
+
+        public NavSearchViewModel()
+        {
+            _allData = new ObservableCollection<MonGeneral>();
+
+            // refresh handling subscriptions
+            // SearchText
+            this.WhenAnyValue(o => o.SearchText)
+                .Subscribe(o => this.RaisePropertyChanged(nameof(DataFiltered)));
+            this.WhenAnyValue(o => o.DataFiltered)
+                .Subscribe(o => this.RaisePropertyChanged(nameof(DataFilteredCount)));
+
+            // DataInstances
+            this.WhenAnyValue(o => o.DataInstances)
+                .Subscribe(o => this.RaisePropertyChanged(nameof(DataFiltered)));
+
+
+            #if MOCKED
+            var gen1 = new MonGeneral()
+            {
+                InstanceIdentifier = "inst1",
+            };
+            gen1.Items.Add(new MonItemGeneral() { Name = "Fee.Foo.Item1", Caption = "this is item1", ViewType = MonItemGeneral.MonViewType.Item });
+            gen1.Items.Add(new MonItemGeneral() { Name = "Fee.Foo.Item2", Caption = "this is item2", ViewType = MonItemGeneral.MonViewType.List });
+            gen1.Items.Add(new MonItemGeneral() { Name = "Fee.Foo.Item3", Caption = "this is item3", ViewType = MonItemGeneral.MonViewType.Item });
+            var gen2 = new MonGeneral()
+            {
+                InstanceIdentifier = "inst2",
+            };
+            gen2.Items.Add(new MonItemGeneral() { Name = "Fee.Frr.Item1", Caption = "this is item1", ViewType = MonItemGeneral.MonViewType.Item });
+            gen2.Items.Add(new MonItemGeneral() { Name = "Fee.Frr.Item2", Caption = "this is item2", ViewType = MonItemGeneral.MonViewType.Item });
+            gen2.Items.Add(new MonItemGeneral() { Name = "Fee.Frr.Item3", Caption = "this is item3", ViewType = MonItemGeneral.MonViewType.Item });
+
+            _allData.Add(gen1);
+            _allData.Add(gen2);
+            #endif
+        }
     }
 }

+ 43 - 9
Workbench/QMonitor/qmonlib.ui/Views/MainView.axaml

@@ -18,16 +18,50 @@
                CompactPaneLength="32"
                OpenPaneLength="296">
         <SplitView.Pane>
-            <Panel>
-                <Button VerticalAlignment="Top" Width="32" Height="32" HorizontalAlignment="Right">
-                    <Button.Content>
-                        <Image Source="/Images/32/adjust.png" />
-                    </Button.Content>
-                </Button>
+            <!--[+]Split LVL 0.1-->
+            <SplitView IsPaneOpen="true"
+                       DisplayMode="Inline"
+                       OpenPaneLength="32"
+                       PanePlacement="Right"
+                       >
+                <SplitView.Pane>
+                    <!-- Filter section command buttons -->
+                    <Grid VerticalAlignment="Top">
+                        <Grid.ColumnDefinitions>
+                            <ColumnDefinition Width="32" />
+                        </Grid.ColumnDefinitions>
+                        <Grid.RowDefinitions>
+                            <RowDefinition Height="35"/>
+                            <RowDefinition Height="35"/>
+                        </Grid.RowDefinitions>
+                        <Button Width="32" Height="32" Grid.Column="0" Grid.Row="0">
+                            <Button.Content>
+                                <Image Source="/Images/32/adjust.png" />
+                            </Button.Content>
+                        </Button>
+                        <Button Width="32" Height="32" Grid.Column="0" Grid.Row="1">
+                            <Button.Content>
+                                <Image Source="/Images/32/gear.png" />
+                            </Button.Content>
+                        </Button>
+                    </Grid>
+                </SplitView.Pane>
                 <!-- Filter section -->
-                <vw-navigator:NavFilter />
-                <vw-navigator:NavGeneralMetadata />
-            </Panel>
+                <Panel>
+                    <Grid>
+                        <Grid.ColumnDefinitions>
+                            <ColumnDefinition Width="*" />
+                        </Grid.ColumnDefinitions>
+                        <Grid.RowDefinitions>
+                            <RowDefinition Height="*" />
+                            <RowDefinition Height="*" />
+                        </Grid.RowDefinitions>
+                    <vw-navigator:NavFilter Grid.Column="0" Grid.Row="0" />
+                    <vw-navigator:NavGeneralMetadata  Grid.Column="0" Grid.Row="1" />
+                    </Grid>
+                </Panel>
+            </SplitView>
+            <!--[-]Split LVL 0.1-->
         </SplitView.Pane>
         <!--[+]Split LVL 1-->
         <SplitView IsPaneOpen="true"

+ 33 - 2
Workbench/QMonitor/qmonlib.ui/Views/Navigator/NavFilter.axaml

@@ -21,6 +21,10 @@
             <ColumnDefinition Width="Auto" />
             <ColumnDefinition Width="32" />
         </Grid.ColumnDefinitions>
+        <Grid.RowDefinitions>
+            <RowDefinition Height="Auto" />
+            <RowDefinition Height="Auto" />
+        </Grid.RowDefinitions>
 
         <!-- textbox: filter input -->
         <TextBox Name="tbSearch"
@@ -28,7 +32,7 @@
                  Watermark="Type pattern filter"
                  FlowDirection="LeftToRight"
                  Grid.Column="0"
-                 Grid.Row="0">
+                 Grid.Row="1">
             <ToolTip.Tip>
                 Put pattern like (use * for any character) string to filter requested values from list
             </ToolTip.Tip>
@@ -39,7 +43,7 @@
             Width="32" Height="32"
             VerticalAlignment="Top"
             Grid.Column="1"
-            Grid.Row="0">
+            Grid.Row="1">
             <Button.Content>
                 X
             </Button.Content>
@@ -47,5 +51,32 @@
                 Clears filter pattern text box
             </ToolTip.Tip>
         </Button>
+  
+        <!-- combobox: identifier selection -->
+        <Expander Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2" VerticalAlignment="Top">
+            <Expander.Header>
+                <TextBlock>
+                    <TextBlock.Text>
+                        <MultiBinding StringFormat="{}Select source identifiers ({1}/{0})">
+                            <Binding Path="DataInstancesCount" />
+                            <Binding Path="DataInstancesSelectedCount" />
+                        </MultiBinding>
+                    </TextBlock.Text>
+                </TextBlock>
+            </Expander.Header>
+            <ListBox Name="lbIdentifiers" ItemsSource="{Binding DataInstances}">
+                <ListBox.ItemTemplate>
+                    <DataTemplate>
+                        <Panel>
+                            <CheckBox IsChecked="{Binding IsChecked}" Content="{Binding Name}"
+                                      />
+                        </Panel>
+                    </DataTemplate>
+                </ListBox.ItemTemplate>
+            </ListBox>
+            <ToolTip.Tip>
+                Select allowed source identifier instances to show in source channel list
+            </ToolTip.Tip>
+        </Expander>
     </Grid>
 </UserControl>

+ 7 - 11
Workbench/QMonitor/qmonlib.ui/Views/Navigator/NavGeneralMetadata.axaml

@@ -3,10 +3,11 @@
              xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
              xmlns:vm-navigator="clr-namespace:qmonlib.ui.ViewModels.Navigator"
-             x:DataType="vm-navigator:NavSearchViewModel"
              mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
-             x:Class="qmonlib.ui.Views.Navigator.NavGeneralMetadata">
-    <Grid>
+             x:Class="qmonlib.ui.Views.Navigator.NavGeneralMetadata"
+             x:CompileBindings="False"
+             >
+    <Grid DataContext="{Binding NavSearch}">
         <Grid.ColumnDefinitions>
             <ColumnDefinition Width="*" />
         </Grid.ColumnDefinitions>
@@ -16,17 +17,12 @@
         </Grid.RowDefinitions>
         
         <!-- list: shows general metadata (filtered) -->
-        <!--<ListBox Grid.Row="1" Items="{Binding SearchResults}" SelectedItem="{Binding SelectedSearchResult}">
+        <ListBox Grid.Row="1" ItemsSource="{Binding DataFiltered}" >
             <ListBox.ItemTemplate>
                 <DataTemplate>
-                    <StackPanel Orientation="Horizontal">
-                        <TextBlock Text="{Binding Name}" />
-                        <TextBlock Text="{Binding Path}" />
-                    </StackPanel>
+                    <TextBlock Text="{Binding Name}"/>
                 </DataTemplate>
             </ListBox.ItemTemplate>
-        </ListBox>-->
-
-
+        </ListBox>
     </Grid>
 </UserControl>

+ 9 - 0
Workbench/QMonitor/qmonlib.ui/qmonlib.ui.csproj

@@ -5,6 +5,9 @@
     <LangVersion>latest</LangVersion>
     <AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
+    <DefineConstants>$(DefineConstants);MOCKED</DefineConstants>
+  </PropertyGroup>
 
   
   <ItemGroup>
@@ -14,6 +17,7 @@
   
   <ItemGroup>
     <None Remove="Images\32\adjust.png" />
+    <None Remove="Images\32\gear.png" />
     <None Remove="Images\32\log.png" />
   </ItemGroup>
 
@@ -29,6 +33,7 @@
 
   <ItemGroup>
     <AvaloniaResource Include="Images\32\adjust.png" />
+    <AvaloniaResource Include="Images\32\gear.png" />
     <AvaloniaResource Include="Images\32\log.png" />
   </ItemGroup>
 
@@ -44,4 +49,8 @@
       <DependentUpon>NavGeneralMetadata.axaml</DependentUpon>
     </Compile>
   </ItemGroup>
+
+  <ItemGroup>
+    <Folder Include="Models\Metadata\" />
+  </ItemGroup>
 </Project>