mirror of
https://github.com/awatertrevi/xamarin-neo4j.git
synced 2026-09-22 09:05:29 +00:00
Pretty much finished the app
This commit is contained in:
@@ -0,0 +1,23 @@
|
|||||||
|
//
|
||||||
|
// QueryEditorRenderer.cs
|
||||||
|
//
|
||||||
|
// Trevi Awater
|
||||||
|
// 13-01-2022
|
||||||
|
//
|
||||||
|
// © Xamarin.Neo4j.iOS
|
||||||
|
//
|
||||||
|
|
||||||
|
using UIKit;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
using Xamarin.Forms.Platform.iOS;
|
||||||
|
using Xamarin.Neo4j.Controls;
|
||||||
|
using Xamarin.Neo4j.iOS.CustomRenderers;
|
||||||
|
|
||||||
|
[assembly: ExportRenderer(typeof(QueryEditor), typeof(QueryEditorRenderer))]
|
||||||
|
namespace Xamarin.Neo4j.iOS.CustomRenderers
|
||||||
|
{
|
||||||
|
public class QueryEditorRenderer : EditorRenderer
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,43 +2,43 @@
|
|||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
<key>UIDeviceFamily</key>
|
<key>UIDeviceFamily</key>
|
||||||
<array>
|
<array>
|
||||||
<integer>1</integer>
|
<integer>1</integer>
|
||||||
<integer>2</integer>
|
<integer>2</integer>
|
||||||
</array>
|
</array>
|
||||||
<key>UISupportedInterfaceOrientations</key>
|
<key>UISupportedInterfaceOrientations</key>
|
||||||
<array>
|
<array>
|
||||||
<string>UIInterfaceOrientationPortrait</string>
|
<string>UIInterfaceOrientationPortrait</string>
|
||||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||||
</array>
|
</array>
|
||||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||||
<array>
|
<array>
|
||||||
<string>UIInterfaceOrientationPortrait</string>
|
<string>UIInterfaceOrientationPortrait</string>
|
||||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||||
</array>
|
</array>
|
||||||
<key>MinimumOSVersion</key>
|
<key>MinimumOSVersion</key>
|
||||||
<string>14.2</string>
|
<string>14.2</string>
|
||||||
<key>CFBundleDisplayName</key>
|
<key>CFBundleDisplayName</key>
|
||||||
<string>Pocket Graph</string>
|
<string>PocketGraph</string>
|
||||||
<key>CFBundleIdentifier</key>
|
<key>CFBundleIdentifier</key>
|
||||||
<string>nl.resoftware.xamarin-neo4j</string>
|
<string>nl.resoftware.pocketgraph</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>1.0</string>
|
<string>1.0.1</string>
|
||||||
<key>UILaunchStoryboardName</key>
|
<key>UILaunchStoryboardName</key>
|
||||||
<string>LaunchScreen</string>
|
<string>LaunchScreen</string>
|
||||||
<key>CFBundleName</key>
|
<key>CFBundleName</key>
|
||||||
<string>Pocket Graph</string>
|
<string>PocketGraph</string>
|
||||||
<key>XSAppIconAssets</key>
|
<key>XSAppIconAssets</key>
|
||||||
<string>Assets.xcassets/AppIcon.appiconset</string>
|
<string>Assets.xcassets/AppIcon.appiconset</string>
|
||||||
<key>UIAppFonts</key>
|
<key>UIAppFonts</key>
|
||||||
<array>
|
<array>
|
||||||
<string>iconize-fontawesome-regular.ttf</string>
|
<string>iconize-fontawesome-regular.ttf</string>
|
||||||
<string>iconize-fontawesome-solid.ttf</string>
|
<string>iconize-fontawesome-solid.ttf</string>
|
||||||
<string>iconize-fontawesome-brands.ttf</string>
|
<string>iconize-fontawesome-brands.ttf</string>
|
||||||
</array>
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="19529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
||||||
|
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||||
|
<dependencies>
|
||||||
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19519"/>
|
||||||
|
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||||
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
|
</dependencies>
|
||||||
|
<scenes>
|
||||||
|
<!--View Controller-->
|
||||||
|
<scene sceneID="EHf-IW-A2E">
|
||||||
|
<objects>
|
||||||
|
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
|
||||||
|
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
|
<subviews>
|
||||||
|
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" image="logo.png" translatesAutoresizingMaskIntoConstraints="NO" id="198">
|
||||||
|
<rect key="frame" x="87" y="384" width="240" height="128"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="width" constant="240" id="623"/>
|
||||||
|
<constraint firstAttribute="height" constant="128" id="830"/>
|
||||||
|
</constraints>
|
||||||
|
</imageView>
|
||||||
|
</subviews>
|
||||||
|
<viewLayoutGuide key="safeArea" id="1038"/>
|
||||||
|
<color key="backgroundColor" red="0.19136750699999999" green="0.2006954849" blue="0.2327556908" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstItem="198" firstAttribute="centerX" secondItem="1038" secondAttribute="centerX" id="201"/>
|
||||||
|
<constraint firstItem="1038" firstAttribute="centerY" secondItem="198" secondAttribute="centerY" id="203"/>
|
||||||
|
</constraints>
|
||||||
|
</view>
|
||||||
|
</viewController>
|
||||||
|
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||||
|
</objects>
|
||||||
|
<point key="canvasLocation" x="53" y="375"/>
|
||||||
|
</scene>
|
||||||
|
</scenes>
|
||||||
|
<resources>
|
||||||
|
<image name="logo.png" width="512" height="512"/>
|
||||||
|
</resources>
|
||||||
|
</document>
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6245" systemVersion="13F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="X5k-f2-b5h">
|
|
||||||
<dependencies>
|
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6238"/>
|
|
||||||
</dependencies>
|
|
||||||
<scenes>
|
|
||||||
<!--View Controller-->
|
|
||||||
<scene sceneID="gAE-YM-kbH">
|
|
||||||
<objects>
|
|
||||||
<viewController id="X5k-f2-b5h" sceneMemberID="viewController">
|
|
||||||
<layoutGuides>
|
|
||||||
<viewControllerLayoutGuide type="top" id="Y8P-hJ-Z43"/>
|
|
||||||
<viewControllerLayoutGuide type="bottom" id="9ZL-r4-8FZ"/>
|
|
||||||
</layoutGuides>
|
|
||||||
<view key="view" contentMode="scaleToFill" id="yd7-JS-zBw">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
||||||
<subviews>
|
|
||||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" misplaced="YES" image="Icon-60.png" translatesAutoresizingMaskIntoConstraints="NO" id="23">
|
|
||||||
<rect key="frame" x="270" y="270" width="60" height="60"/>
|
|
||||||
<rect key="contentStretch" x="0.0" y="0.0" width="0.0" height="0.0"/>
|
|
||||||
</imageView>
|
|
||||||
</subviews>
|
|
||||||
<color key="backgroundColor" red="0.20392156862745098" green="0.59607843137254901" blue="0.85882352941176465" alpha="1" colorSpace="calibratedRGB"/>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstItem="23" firstAttribute="centerY" secondItem="yd7-JS-zBw" secondAttribute="centerY" priority="1" id="39"/>
|
|
||||||
<constraint firstItem="23" firstAttribute="centerX" secondItem="yd7-JS-zBw" secondAttribute="centerX" priority="1" id="41"/>
|
|
||||||
</constraints>
|
|
||||||
</view>
|
|
||||||
</viewController>
|
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="XAI-xm-WK6" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
|
||||||
</objects>
|
|
||||||
<point key="canvasLocation" x="349" y="339"/>
|
|
||||||
</scene>
|
|
||||||
</scenes>
|
|
||||||
<resources>
|
|
||||||
<image name="Icon-60.png" width="180" height="180"/>
|
|
||||||
</resources>
|
|
||||||
</document>
|
|
||||||
BIN
Xamarin.Neo4j/Xamarin.Neo4j/Xamarin.Neo4j.iOS/Resources/logo.png
Normal file
BIN
Xamarin.Neo4j/Xamarin.Neo4j/Xamarin.Neo4j.iOS/Resources/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 63 KiB |
@@ -0,0 +1,30 @@
|
|||||||
|
//
|
||||||
|
// ScreenSizeService.cs
|
||||||
|
//
|
||||||
|
// Trevi Awater
|
||||||
|
// 13-01-2022
|
||||||
|
//
|
||||||
|
// © Xamarin.Neo4j.iOS
|
||||||
|
//
|
||||||
|
|
||||||
|
using UIKit;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
using Xamarin.Neo4j.iOS.Services;
|
||||||
|
using Xamarin.Neo4j.Services;
|
||||||
|
|
||||||
|
[assembly: Dependency(typeof(ScreenSizeService))]
|
||||||
|
namespace Xamarin.Neo4j.iOS.Services
|
||||||
|
{
|
||||||
|
public class ScreenSizeService : IScreenSizeService
|
||||||
|
{
|
||||||
|
public int GetScreenHeight()
|
||||||
|
{
|
||||||
|
return (int)UIScreen.MainScreen.Bounds.Height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetScreenWidth()
|
||||||
|
{
|
||||||
|
return (int)UIScreen.MainScreen.Bounds.Width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -94,8 +94,10 @@
|
|||||||
<MtouchLink>SdkOnly</MtouchLink>
|
<MtouchLink>SdkOnly</MtouchLink>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="CustomRenderers\QueryEditorRenderer.cs" />
|
||||||
<Compile Include="Main.cs" />
|
<Compile Include="Main.cs" />
|
||||||
<Compile Include="AppDelegate.cs" />
|
<Compile Include="AppDelegate.cs" />
|
||||||
|
<Compile Include="Services\ScreenSizeService.cs" />
|
||||||
<None Include="Entitlements.plist" />
|
<None Include="Entitlements.plist" />
|
||||||
<None Include="Info.plist" />
|
<None Include="Info.plist" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
@@ -119,7 +121,7 @@
|
|||||||
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\Icon-76x76@2x.png" />
|
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\Icon-76x76@2x.png" />
|
||||||
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\Icon-83.5@2x.png" />
|
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\Icon-83.5@2x.png" />
|
||||||
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\Icon-marketing-1024x1024.png" />
|
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\Icon-marketing-1024x1024.png" />
|
||||||
<InterfaceDefinition Include="Resources\LaunchScreen.storyboard" />
|
<InterfaceDefinition Include="LaunchScreen.storyboard" />
|
||||||
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\Contents.json">
|
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\Contents.json">
|
||||||
<Visible>false</Visible>
|
<Visible>false</Visible>
|
||||||
</ImageAsset>
|
</ImageAsset>
|
||||||
@@ -143,6 +145,8 @@
|
|||||||
<BundleResource Include="Resources\iconize-fontawesome-brands.ttf" />
|
<BundleResource Include="Resources\iconize-fontawesome-brands.ttf" />
|
||||||
<BundleResource Include="Resources\iconize-fontawesome-regular.ttf" />
|
<BundleResource Include="Resources\iconize-fontawesome-regular.ttf" />
|
||||||
<BundleResource Include="Resources\iconize-fontawesome-solid.ttf" />
|
<BundleResource Include="Resources\iconize-fontawesome-solid.ttf" />
|
||||||
|
<BundleResource Include="Resources\logo.png" />
|
||||||
|
<BundleResource Include="Resources\resoftware.png" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
|
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
|
||||||
</Project>
|
</Project>
|
||||||
@@ -2,36 +2,4 @@
|
|||||||
<Application xmlns="http://xamarin.com/schemas/2014/forms"
|
<Application xmlns="http://xamarin.com/schemas/2014/forms"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||||
x:Class="Xamarin.Neo4j.App">
|
x:Class="Xamarin.Neo4j.App">
|
||||||
<Application.Resources>
|
|
||||||
<Color x:Key="Glitter">#e4ecf5</Color>
|
|
||||||
<Color x:Key="EbonyClay">#31333b</Color>
|
|
||||||
|
|
||||||
<OnPlatform x:TypeArguments="x:String" x:Key="FontAwesomeBrands">
|
|
||||||
<On Platform="Android" Value="FontAwesome5Brands.ttf#Regular" />
|
|
||||||
<On Platform="iOS" Value="FontAwesome5Brands-Regular" />
|
|
||||||
</OnPlatform>
|
|
||||||
|
|
||||||
<OnPlatform x:TypeArguments="x:String" x:Key="FontAwesomeSolid">
|
|
||||||
<On Platform="Android" Value="FontAwesome5Solid.ttf#Regular" />
|
|
||||||
<On Platform="iOS" Value="FontAwesome5Free-Solid" />
|
|
||||||
</OnPlatform>
|
|
||||||
|
|
||||||
<OnPlatform x:TypeArguments="x:String" x:Key="FontAwesomeRegular">
|
|
||||||
<On Platform="Android" Value="FontAwesome5Regular.ttf#Regular" />
|
|
||||||
<On Platform="iOS" Value="FontAwesome5Free-Regular" />
|
|
||||||
</OnPlatform>
|
|
||||||
|
|
||||||
<Style TargetType="ContentPage" ApplyToDerivedTypes="True">
|
|
||||||
<Setter Property="BackgroundColor" Value="{StaticResource Glitter}" />
|
|
||||||
</Style>
|
|
||||||
|
|
||||||
<Style TargetType="ListView">
|
|
||||||
<Setter Property="BackgroundColor" Value="Transparent" />
|
|
||||||
</Style>
|
|
||||||
|
|
||||||
<Style TargetType="NavigationPage">
|
|
||||||
<Setter Property="BarBackgroundColor" Value="{StaticResource EbonyClay}"/>
|
|
||||||
<Setter Property="BarTextColor" Value="White" />
|
|
||||||
</Style>
|
|
||||||
</Application.Resources>
|
|
||||||
</Application>
|
</Application>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
using Xamarin.Forms.Xaml;
|
using Xamarin.Forms.Xaml;
|
||||||
using Xamarin.Neo4j.Pages;
|
using Xamarin.Neo4j.Pages;
|
||||||
|
using Xamarin.Neo4j.Themes;
|
||||||
|
|
||||||
[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
|
[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
|
||||||
|
|
||||||
@@ -13,9 +14,24 @@ namespace Xamarin.Neo4j
|
|||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
|
SetTheme(Current.RequestedTheme);
|
||||||
|
|
||||||
MainPage = new NavigationPage(new RootPage());
|
MainPage = new NavigationPage(new RootPage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void SetTheme(OSAppTheme theme)
|
||||||
|
{
|
||||||
|
Resources = theme switch
|
||||||
|
{
|
||||||
|
OSAppTheme.Dark => new DarkTheme(),
|
||||||
|
OSAppTheme.Light => new LightTheme(),
|
||||||
|
|
||||||
|
_ => new LightTheme()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
protected override void OnStart()
|
protected override void OnStart()
|
||||||
{
|
{
|
||||||
// Handle when your app starts
|
// Handle when your app starts
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<ViewCell xmlns="http://xamarin.com/schemas/2014/forms"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||||
|
xmlns:fonts="clr-namespace:Xamarin.Neo4j.Fonts;assembly=Xamarin.Neo4j"
|
||||||
|
x:Class="Xamarin.Neo4j.Controls.ConnectionCell">
|
||||||
|
<Grid Padding="15, 10">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="1*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<Label Grid.Column="0" x:Name="isActiveIndicator" Text="{x:Static fonts:FontAwesomeSolid.Circle}" FontFamily="{StaticResource FontAwesomeSolid}" VerticalOptions="Center" TextColor="#34C759" Margin="0 ,0, 7.5, 0"/>
|
||||||
|
|
||||||
|
<StackLayout Grid.Column="1" Spacing="2">
|
||||||
|
<Label Text="{Binding Name}" />
|
||||||
|
<Label Text="{Binding Host}" FontSize="Small" TextColor="{StaticResource SecondaryTextColor}" />
|
||||||
|
</StackLayout>
|
||||||
|
</Grid>
|
||||||
|
</ViewCell>
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
using Xamarin.Forms;
|
||||||
|
using Xamarin.Forms.Xaml;
|
||||||
|
|
||||||
|
namespace Xamarin.Neo4j.Controls
|
||||||
|
{
|
||||||
|
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||||
|
public partial class ConnectionCell : ViewCell
|
||||||
|
{
|
||||||
|
public ConnectionCell()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
|
isActiveIndicator.SetBinding(VisualElement.IsVisibleProperty, new Binding(nameof(IsActive), source: this));
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Bindable Properties
|
||||||
|
|
||||||
|
public bool IsActive
|
||||||
|
{
|
||||||
|
get => (bool)GetValue(IsActiveProperty);
|
||||||
|
set => SetValue(IsActiveProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BindableProperty IsActiveProperty = BindableProperty.Create("IsActive", typeof(bool),
|
||||||
|
typeof(ConnectionCell), false, BindingMode.OneWay);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
|
|
||||||
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
|
||||||
xmlns:pancakeView="clr-namespace:Xamarin.Forms.PancakeView;assembly=Xamarin.Forms.PancakeView"
|
|
||||||
xmlns:fonts="clr-namespace:Xamarin.Neo4j.Fonts;assembly=Xamarin.Neo4j"
|
|
||||||
x:Class="Xamarin.Neo4j.Controls.QueryBuilder">
|
|
||||||
<pancakeView:PancakeView BackgroundColor="White" CornerRadius="2" Padding="4" Margin="16">
|
|
||||||
<pancakeView:PancakeView CornerRadius="2">
|
|
||||||
<pancakeView:PancakeView.Border>
|
|
||||||
<pancakeView:Border Thickness="2" Color="#d8e5f1" />
|
|
||||||
</pancakeView:PancakeView.Border>
|
|
||||||
|
|
||||||
<StackLayout Orientation="Horizontal">
|
|
||||||
<Editor x:Name="editor" HorizontalOptions="FillAndExpand" AutoSize="TextChanges" />
|
|
||||||
|
|
||||||
<Button Clicked="InvokeExecuteQuery" Text="{x:Static fonts:FontAwesomeSolid.Play}" FontFamily="{StaticResource FontAwesomeSolid}" VerticalOptions="CenterAndExpand" HorizontalOptions="End" FontSize="20" Margin="0, 0, 5, 0" />
|
|
||||||
</StackLayout>
|
|
||||||
</pancakeView:PancakeView>
|
|
||||||
</pancakeView:PancakeView>
|
|
||||||
</ContentView>
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
using Xamarin.Forms;
|
|
||||||
using Xamarin.Forms.Xaml;
|
|
||||||
|
|
||||||
namespace Xamarin.Neo4j.Controls
|
|
||||||
{
|
|
||||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
|
||||||
public partial class QueryBuilder : ContentView
|
|
||||||
{
|
|
||||||
public event EventHandler ExecuteQuery;
|
|
||||||
|
|
||||||
public QueryBuilder()
|
|
||||||
{
|
|
||||||
InitializeComponent();
|
|
||||||
|
|
||||||
editor.SetBinding(Editor.TextProperty, new Binding(nameof(Query), source: this));
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Bindable Properties
|
|
||||||
|
|
||||||
public string Query
|
|
||||||
{
|
|
||||||
get => (string)GetValue(QueryProperty);
|
|
||||||
set => SetValue(QueryProperty, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BindableProperty QueryProperty = BindableProperty.Create("Query", typeof(string),
|
|
||||||
typeof(QueryBuilder), string.Empty, BindingMode.TwoWay);
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
private void InvokeExecuteQuery (object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
ExecuteQuery?.Invoke(sender, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
//
|
||||||
|
// QueryEditor.cs
|
||||||
|
//
|
||||||
|
// Trevi Awater
|
||||||
|
// 13-01-2022
|
||||||
|
//
|
||||||
|
// © Xamarin.Neo4j
|
||||||
|
//
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
|
||||||
|
namespace Xamarin.Neo4j.Controls
|
||||||
|
{
|
||||||
|
public class QueryEditor : Editor
|
||||||
|
{
|
||||||
|
public double MaxHeight { get; set; }
|
||||||
|
|
||||||
|
protected override SizeRequest OnMeasure(double widthConstraint, double heightConstraint)
|
||||||
|
{
|
||||||
|
var sizeRequest = base.OnMeasure(widthConstraint, heightConstraint);
|
||||||
|
|
||||||
|
var newHeight = sizeRequest.Request.Height;
|
||||||
|
|
||||||
|
if (newHeight > MaxHeight)
|
||||||
|
newHeight = MaxHeight;
|
||||||
|
|
||||||
|
return new SizeRequest(new Size(sizeRequest.Request.Width, newHeight));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
|
|
||||||
<ViewCell xmlns="http://xamarin.com/schemas/2014/forms"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
|
||||||
xmlns:fonts="clr-namespace:Xamarin.Neo4j.Fonts;assembly=Xamarin.Neo4j"
|
|
||||||
x:Class="Xamarin.Neo4j.Controls.QueryResultCell">
|
|
||||||
<StackLayout Orientation="Horizontal">
|
|
||||||
<Label Text="{Binding Query}" />
|
|
||||||
<Button Clicked="OpenNeovis" Text="{x:Static fonts:FontAwesomeSolid.ProjectDiagram}" FontFamily="{StaticResource FontAwesomeSolid}" VerticalOptions="CenterAndExpand" FontSize="20" Margin="0, 0, 5, 0" />
|
|
||||||
</StackLayout>
|
|
||||||
</ViewCell>
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
using Xamarin.Forms;
|
|
||||||
using Xamarin.Forms.Xaml;
|
|
||||||
using Xamarin.Neo4j.Models;
|
|
||||||
using Xamarin.Neo4j.Pages;
|
|
||||||
|
|
||||||
namespace Xamarin.Neo4j.Controls
|
|
||||||
{
|
|
||||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
|
||||||
public partial class QueryResultCell : ViewCell
|
|
||||||
{
|
|
||||||
public QueryResult QueryResult => (QueryResult) BindingContext;
|
|
||||||
|
|
||||||
public QueryResultCell()
|
|
||||||
{
|
|
||||||
InitializeComponent();
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void OpenNeovis(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
await App.Current.MainPage.Navigation.PushAsync(new VisualizationPage(QueryResult));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||||
|
xmlns:fonts="clr-namespace:Xamarin.Neo4j.Fonts;assembly=Xamarin.Neo4j"
|
||||||
|
xmlns:pancakeView="clr-namespace:Xamarin.Forms.PancakeView;assembly=Xamarin.Forms.PancakeView"
|
||||||
|
Margin="0, 0, 0, 25"
|
||||||
|
x:Class="Xamarin.Neo4j.Controls.QueryResultView">
|
||||||
|
<StackLayout Orientation="Vertical" Spacing="0">
|
||||||
|
<pancakeView:PancakeView>
|
||||||
|
<pancakeView:PancakeView.Border>
|
||||||
|
<pancakeView:Border Thickness="4" Color="{StaticResource QueryTextBorder}" />
|
||||||
|
</pancakeView:PancakeView.Border>
|
||||||
|
<Label Text="{Binding Query}" Padding="8" HorizontalOptions="FillAndExpand" BackgroundColor="{StaticResource Extreme}" />
|
||||||
|
</pancakeView:PancakeView>
|
||||||
|
|
||||||
|
<WebView x:Name="graphView" HorizontalOptions="FillAndExpand" IsVisible="{Binding CanDisplayGraph}" HeightRequest="200" />
|
||||||
|
|
||||||
|
<Grid BackgroundColor="{StaticResource QueryActionBar}" Padding="5">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="1*" />
|
||||||
|
<ColumnDefinition Width="1*" />
|
||||||
|
<ColumnDefinition Width="1*" />
|
||||||
|
<ColumnDefinition Width="1*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<Button Grid.Column="0" Clicked="SaveQuery" Text="{x:Static fonts:FontAwesomeSolid.Star}" BackgroundColor="Transparent" TextColor="White" FontFamily="{StaticResource FontAwesomeSolid}" FontSize="20" />
|
||||||
|
<Button Grid.Column="1" Clicked="OpenNeovis" Text="{x:Static fonts:FontAwesomeSolid.Expand}" BackgroundColor="Transparent" IsEnabled="{Binding CanDisplayGraph}" TextColor="White" FontFamily="{StaticResource FontAwesomeSolid}" FontSize="20 "/>
|
||||||
|
<Button Grid.Column="2" Clicked="OpenTableView" Text="{x:Static fonts:FontAwesomeSolid.List}" BackgroundColor="Transparent" TextColor="White" FontFamily="{StaticResource FontAwesomeSolid}" FontSize="20 "/>
|
||||||
|
<Button Grid.Column="3" Clicked="CloseResultView" Text="{x:Static fonts:FontAwesomeSolid.Times}" BackgroundColor="Transparent" TextColor="White" FontFamily="{StaticResource FontAwesomeSolid}" FontSize="20 "/>
|
||||||
|
</Grid>
|
||||||
|
</StackLayout>
|
||||||
|
</ContentView>
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Acr.UserDialogs;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
using Xamarin.Forms.Xaml;
|
||||||
|
using Xamarin.Neo4j.Managers;
|
||||||
|
using Xamarin.Neo4j.Models;
|
||||||
|
using Xamarin.Neo4j.Pages;
|
||||||
|
using Xamarin.Neo4j.Utilities;
|
||||||
|
|
||||||
|
namespace Xamarin.Neo4j.Controls
|
||||||
|
{
|
||||||
|
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||||
|
public partial class QueryResultView : ContentView
|
||||||
|
{
|
||||||
|
private QueryResult QueryResult => (QueryResult) BindingContext;
|
||||||
|
|
||||||
|
public event EventHandler<GenericEventArgs<QueryResult>> CloseRequested;
|
||||||
|
|
||||||
|
private string _neovisHtml;
|
||||||
|
|
||||||
|
public QueryResultView()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnPropertyChanged(string propertyName = null)
|
||||||
|
{
|
||||||
|
base.OnPropertyChanged(propertyName);
|
||||||
|
|
||||||
|
if (propertyName == nameof(BindingContext))
|
||||||
|
{
|
||||||
|
ParseNeovisHtml();
|
||||||
|
|
||||||
|
graphView.Source = new HtmlWebViewSource()
|
||||||
|
{
|
||||||
|
Html = _neovisHtml
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ParseNeovisHtml()
|
||||||
|
{
|
||||||
|
var assembly = Assembly.GetExecutingAssembly();
|
||||||
|
var resourceName = "Xamarin.Neo4j.Visualization.neovis.html";
|
||||||
|
|
||||||
|
using (var stream = assembly.GetManifestResourceStream(resourceName))
|
||||||
|
using (var reader = new StreamReader(stream))
|
||||||
|
{
|
||||||
|
var result = reader.ReadToEnd();
|
||||||
|
|
||||||
|
result = result.Replace("{{host}}", QueryResult.ConnectionString.Host);
|
||||||
|
result = result.Replace("{{port}}", QueryResult.ConnectionString.Port.ToString());
|
||||||
|
result = result.Replace("{{database}}", QueryResult.ConnectionString.Database);
|
||||||
|
result = result.Replace("{{username}}", QueryResult.ConnectionString.Username);
|
||||||
|
result = result.Replace("{{password}}", QueryResult.ConnectionString.Password);
|
||||||
|
result = result.Replace("{{encryption}}", QueryResult.ConnectionString.Encrypted ? "ENCRYPTION_ON" : "ENCRYPTION_OFF");
|
||||||
|
result = result.Replace("{{query}}", QueryResult.Query);
|
||||||
|
result = result.Replace("{{backgroundColor}}", App.Current.RequestedTheme == OSAppTheme.Dark ? "#292C31" : "#FFFFFF");
|
||||||
|
|
||||||
|
_neovisHtml = result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private async void OpenNeovis(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
await Application.Current.MainPage.Navigation.PushAsync(new GraphPage(_neovisHtml));
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void SaveQuery(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
var queryNameResult = await UserDialogs.Instance.PromptAsync("How should the query be called?");
|
||||||
|
|
||||||
|
if (queryNameResult.Ok)
|
||||||
|
{
|
||||||
|
var query = new Query()
|
||||||
|
{
|
||||||
|
Id = Guid.NewGuid(),
|
||||||
|
QueryText = QueryResult.Query,
|
||||||
|
Name = queryNameResult.Value,
|
||||||
|
};
|
||||||
|
|
||||||
|
SavedQueryManager.AddSavedQuery(query);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CloseResultView(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
CloseRequested?.Invoke(sender, new GenericEventArgs<QueryResult>(QueryResult));
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void OpenTableView(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
await Application.Current.MainPage.Navigation.PushAsync(new TablePage(QueryResult));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
//
|
||||||
|
// IsActiveConnectionConverter.cs
|
||||||
|
//
|
||||||
|
// Trevi Awater
|
||||||
|
// 13-01-2022
|
||||||
|
//
|
||||||
|
// © Xamarin.Neo4j
|
||||||
|
//
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
using Xamarin.Neo4j.Managers;
|
||||||
|
using Xamarin.Neo4j.Models;
|
||||||
|
|
||||||
|
namespace Xamarin.Neo4j.Converters
|
||||||
|
{
|
||||||
|
public class IsActiveConnectionConverter : IValueConverter
|
||||||
|
{
|
||||||
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
if (value is Neo4jConnectionString targetConnection)
|
||||||
|
return targetConnection.Id == ConnectionStringManager.ActiveConnectionString?.Id;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
//
|
||||||
|
// JsonConvertConverter.cs
|
||||||
|
//
|
||||||
|
// Trevi Awater
|
||||||
|
// 13-01-2022
|
||||||
|
//
|
||||||
|
// © Xamarin.Neo4j
|
||||||
|
//
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
|
||||||
|
namespace Xamarin.Neo4j.Converters
|
||||||
|
{
|
||||||
|
public class JsonConvertConverter : IValueConverter
|
||||||
|
{
|
||||||
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
return JsonConvert.SerializeObject(value, Formatting.Indented);
|
||||||
|
}
|
||||||
|
|
||||||
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,6 +22,8 @@ namespace Xamarin.Neo4j.Managers
|
|||||||
{
|
{
|
||||||
private const string ConnectionStringsKey = "connection_strings";
|
private const string ConnectionStringsKey = "connection_strings";
|
||||||
|
|
||||||
|
public static Neo4jConnectionString ActiveConnectionString { get; set; }
|
||||||
|
|
||||||
public static async Task<List<Neo4jConnectionString>> GetConnectionStrings()
|
public static async Task<List<Neo4jConnectionString>> GetConnectionStrings()
|
||||||
{
|
{
|
||||||
var json = await SecureStorage.GetAsync(ConnectionStringsKey);
|
var json = await SecureStorage.GetAsync(ConnectionStringsKey);
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
//
|
||||||
|
// SavedQueryManager.cs
|
||||||
|
//
|
||||||
|
// Trevi Awater
|
||||||
|
// 11-01-2022
|
||||||
|
//
|
||||||
|
// © Xamarin.Neo4j
|
||||||
|
//
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Xamarin.Essentials;
|
||||||
|
using Xamarin.Neo4j.Models;
|
||||||
|
|
||||||
|
namespace Xamarin.Neo4j.Managers
|
||||||
|
{
|
||||||
|
public class SavedQueryManager
|
||||||
|
{
|
||||||
|
private const string SavedQueriesKey = "saved_queries";
|
||||||
|
|
||||||
|
public static List<Query> GetSavedQueries()
|
||||||
|
{
|
||||||
|
var json = Preferences.Get(SavedQueriesKey, null);
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(json))
|
||||||
|
return new List<Query>();
|
||||||
|
|
||||||
|
return JsonConvert.DeserializeObject<List<Query>>(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void AddSavedQuery(Query query)
|
||||||
|
{
|
||||||
|
var savedQueries = GetSavedQueries();
|
||||||
|
|
||||||
|
savedQueries.Add(query);
|
||||||
|
|
||||||
|
SaveSavedQueries(savedQueries);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SaveSavedQueries(IEnumerable<Query> savedQueries)
|
||||||
|
{
|
||||||
|
var json = JsonConvert.SerializeObject(savedQueries);
|
||||||
|
|
||||||
|
Preferences.Set(SavedQueriesKey, json);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void DeleteSavedQuery(Query query)
|
||||||
|
{
|
||||||
|
var savedQueries = GetSavedQueries();
|
||||||
|
|
||||||
|
savedQueries = savedQueries.Where(cs => cs.Id != query.Id)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
SaveSavedQueries(savedQueries);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
22
Xamarin.Neo4j/Xamarin.Neo4j/Xamarin.Neo4j/Models/Query.cs
Normal file
22
Xamarin.Neo4j/Xamarin.Neo4j/Xamarin.Neo4j/Models/Query.cs
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
//
|
||||||
|
// Query.cs
|
||||||
|
//
|
||||||
|
// Trevi Awater
|
||||||
|
// 11-01-2022
|
||||||
|
//
|
||||||
|
// © Xamarin.Neo4j
|
||||||
|
//
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Xamarin.Neo4j.Models
|
||||||
|
{
|
||||||
|
public class Query
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public string QueryText { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
// © Xamarin.Neo4j
|
// © Xamarin.Neo4j
|
||||||
//
|
//
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Neo4j.Driver;
|
using Neo4j.Driver;
|
||||||
@@ -15,16 +16,18 @@ namespace Xamarin.Neo4j.Models
|
|||||||
{
|
{
|
||||||
public class QueryResult
|
public class QueryResult
|
||||||
{
|
{
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
|
||||||
public bool Success { get; set; }
|
public bool Success { get; set; }
|
||||||
|
|
||||||
|
public bool CanDisplayGraph { get; set; }
|
||||||
|
|
||||||
public string ErrorMessage { get; set; }
|
public string ErrorMessage { get; set; }
|
||||||
|
|
||||||
public string Query { get; set; }
|
public string Query { get; set; }
|
||||||
|
|
||||||
public Neo4jConnectionString ConnectionString { get; set; }
|
public Neo4jConnectionString ConnectionString { get; set; }
|
||||||
|
|
||||||
public IEnumerable<INode> Nodes { get; set; }
|
public Dictionary<string, List<object>> Results { get; set; }
|
||||||
|
|
||||||
public IEnumerable<IRelationship> Relationships { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,17 +32,9 @@
|
|||||||
<Entry Text="{Binding Password}" IsPassword="True" />
|
<Entry Text="{Binding Password}" IsPassword="True" />
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
|
|
||||||
<Grid>
|
<Button Text="Connect" BackgroundColor="#2DB4A8" TextColor="White" Command="{Binding Commands[Connect]}" />
|
||||||
<Grid.ColumnDefinitions>
|
<Button Text="Test" BackgroundColor="Orange" TextColor="White" Command="{Binding Commands[Test]}" />
|
||||||
<ColumnDefinition Width="1*" />
|
<Button Text="Save" BackgroundColor="#89972E" TextColor="White" Command="{Binding Commands[Save]}" />
|
||||||
<ColumnDefinition Width="1*" />
|
|
||||||
<ColumnDefinition Width="1*" />
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
|
|
||||||
<Button Grid.Column="0" Text="Connect" Command="{Binding Commands[Connect]}" />
|
|
||||||
<Button Grid.Column="1" Text="Test" Command="{Binding Commands[Test]}" />
|
|
||||||
<Button Grid.Column="2" Text="Save" Command="{Binding Commands[Save]}" />
|
|
||||||
</Grid>
|
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
</ContentPage.Content>
|
</ContentPage.Content>
|
||||||
|
|||||||
@@ -3,9 +3,17 @@
|
|||||||
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
|
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||||
xmlns:fonts="clr-namespace:Xamarin.Neo4j.Fonts;assembly=Xamarin.Neo4j"
|
xmlns:fonts="clr-namespace:Xamarin.Neo4j.Fonts;assembly=Xamarin.Neo4j"
|
||||||
|
xmlns:controls="clr-namespace:Xamarin.Neo4j.Controls;assembly=Xamarin.Neo4j"
|
||||||
|
xmlns:converters="clr-namespace:Xamarin.Neo4j.Converters;assembly=Xamarin.Neo4j"
|
||||||
x:Class="Xamarin.Neo4j.Pages.ConnectionsPage"
|
x:Class="Xamarin.Neo4j.Pages.ConnectionsPage"
|
||||||
x:Name="connectionsPage"
|
x:Name="connectionsPage"
|
||||||
Title="Connections">
|
Title="Connections">
|
||||||
|
<ContentPage.Resources>
|
||||||
|
<ResourceDictionary>
|
||||||
|
<converters:IsActiveConnectionConverter x:Key="isActiveConnection" />
|
||||||
|
</ResourceDictionary>
|
||||||
|
</ContentPage.Resources>
|
||||||
|
|
||||||
<ContentPage.IconImageSource>
|
<ContentPage.IconImageSource>
|
||||||
<FontImageSource
|
<FontImageSource
|
||||||
FontFamily="{StaticResource FontAwesomeSolid}"
|
FontFamily="{StaticResource FontAwesomeSolid}"
|
||||||
@@ -14,6 +22,14 @@
|
|||||||
</ContentPage.IconImageSource>
|
</ContentPage.IconImageSource>
|
||||||
|
|
||||||
<ContentPage.ToolbarItems>
|
<ContentPage.ToolbarItems>
|
||||||
|
<ToolbarItem Command="{Binding Commands[StartSession]}">
|
||||||
|
<ToolbarItem.IconImageSource>
|
||||||
|
<FontImageSource
|
||||||
|
FontFamily="{StaticResource FontAwesomeSolid}"
|
||||||
|
Glyph="{x:Static fonts:FontAwesomeSolid.Terminal}" Size="20" />
|
||||||
|
</ToolbarItem.IconImageSource>
|
||||||
|
</ToolbarItem>
|
||||||
|
|
||||||
<ToolbarItem Command="{Binding Commands[AddConnection]}">
|
<ToolbarItem Command="{Binding Commands[AddConnection]}">
|
||||||
<ToolbarItem.IconImageSource>
|
<ToolbarItem.IconImageSource>
|
||||||
<FontImageSource
|
<FontImageSource
|
||||||
@@ -24,14 +40,14 @@
|
|||||||
</ContentPage.ToolbarItems>
|
</ContentPage.ToolbarItems>
|
||||||
|
|
||||||
<ContentPage.Content>
|
<ContentPage.Content>
|
||||||
<ListView ItemsSource="{Binding ConnectionStrings}" ItemTapped="StartSession">
|
<ListView ItemsSource="{Binding ConnectionStrings}" HasUnevenRows="True" SelectionMode="None" ItemTapped="SetActive">
|
||||||
<ListView.ItemTemplate>
|
<ListView.ItemTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<TextCell Text="{Binding Name}" Detail="{Binding Host}">
|
<controls:ConnectionCell IsActive="{Binding ., Converter={StaticResource isActiveConnection}}">
|
||||||
<TextCell.ContextActions>
|
<controls:ConnectionCell.ContextActions>
|
||||||
<MenuItem Text="Delete" Command="{Binding BindingContext.Commands[DeleteConnectionString], Source={x:Reference connectionsPage} }" CommandParameter="{Binding .}" IsDestructive="true" />
|
<MenuItem Text="Delete" Command="{Binding BindingContext.Commands[DeleteConnectionString], Source={x:Reference connectionsPage} }" CommandParameter="{Binding .}" IsDestructive="true" />
|
||||||
</TextCell.ContextActions>
|
</controls:ConnectionCell.ContextActions>
|
||||||
</TextCell>
|
</controls:ConnectionCell>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</ListView.ItemTemplate>
|
</ListView.ItemTemplate>
|
||||||
</ListView>
|
</ListView>
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
using Xamarin.Forms.Xaml;
|
using Xamarin.Forms.Xaml;
|
||||||
|
using Xamarin.Neo4j.Managers;
|
||||||
using Xamarin.Neo4j.Models;
|
using Xamarin.Neo4j.Models;
|
||||||
using Xamarin.Neo4j.ViewModels;
|
using Xamarin.Neo4j.ViewModels;
|
||||||
|
|
||||||
@@ -30,11 +31,9 @@ namespace Xamarin.Neo4j.Pages
|
|||||||
base.OnAppearing();
|
base.OnAppearing();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void StartSession(object sender, ItemTappedEventArgs e)
|
private void SetActive(object sender, ItemTappedEventArgs e)
|
||||||
{
|
{
|
||||||
var connectionString = (Neo4jConnectionString)e.Item;
|
ViewModel.SetActiveConnectionString((Neo4jConnectionString)e.Item);
|
||||||
|
|
||||||
await Navigation.PushAsync(new SessionPage(connectionString));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
|
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||||
Title="Graph"
|
Title="Graph"
|
||||||
x:Class="Xamarin.Neo4j.Pages.VisualizationPage">
|
x:Class="Xamarin.Neo4j.Pages.GraphPage">
|
||||||
<ContentPage.Content>
|
<ContentPage.Content>
|
||||||
<WebView Source="{Binding Source}" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" />
|
<WebView Source="{Binding Source}" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" />
|
||||||
</ContentPage.Content>
|
</ContentPage.Content>
|
||||||
@@ -12,13 +12,13 @@ using Xamarin.Neo4j.ViewModels;
|
|||||||
namespace Xamarin.Neo4j.Pages
|
namespace Xamarin.Neo4j.Pages
|
||||||
{
|
{
|
||||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||||
public partial class VisualizationPage : ContentPage
|
public partial class GraphPage : ContentPage
|
||||||
{
|
{
|
||||||
public VisualizationPage(QueryResult queryResult)
|
public GraphPage(string html)
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
BindingContext = new VisualizationViewModel(Navigation, queryResult);
|
BindingContext = new GraphViewModel(Navigation, html);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||||
xmlns:fonts="clr-namespace:Xamarin.Neo4j.Fonts;assembly=Xamarin.Neo4j"
|
xmlns:fonts="clr-namespace:Xamarin.Neo4j.Fonts;assembly=Xamarin.Neo4j"
|
||||||
Title="Queries"
|
Title="Queries"
|
||||||
|
x:Name="queriesPage"
|
||||||
x:Class="Xamarin.Neo4j.Pages.QueriesPage">
|
x:Class="Xamarin.Neo4j.Pages.QueriesPage">
|
||||||
<ContentPage.IconImageSource>
|
<ContentPage.IconImageSource>
|
||||||
<FontImageSource
|
<FontImageSource
|
||||||
@@ -13,10 +14,16 @@
|
|||||||
</ContentPage.IconImageSource>
|
</ContentPage.IconImageSource>
|
||||||
|
|
||||||
<ContentPage.Content>
|
<ContentPage.Content>
|
||||||
<StackLayout>
|
<ListView ItemsSource="{Binding Queries}" ItemTapped="StartSessionWithQuery">
|
||||||
<Label Text="Hello, world!"
|
<ListView.ItemTemplate>
|
||||||
VerticalOptions="CenterAndExpand"
|
<DataTemplate>
|
||||||
HorizontalOptions="CenterAndExpand" />
|
<TextCell Text="{Binding Name}" Detail="{Binding QueryText}">
|
||||||
</StackLayout>
|
<TextCell.ContextActions>
|
||||||
|
<MenuItem Text="Delete" Command="{Binding BindingContext.Commands[DeleteQuery], Source={x:Reference queriesPage} }" CommandParameter="{Binding .}" IsDestructive="true" />
|
||||||
|
</TextCell.ContextActions>
|
||||||
|
</TextCell>
|
||||||
|
</DataTemplate>
|
||||||
|
</ListView.ItemTemplate>
|
||||||
|
</ListView>
|
||||||
</ContentPage.Content>
|
</ContentPage.Content>
|
||||||
</ContentPage>
|
</ContentPage>
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
using Xamarin.Forms.Xaml;
|
using Xamarin.Forms.Xaml;
|
||||||
|
using Xamarin.Neo4j.Models;
|
||||||
using Xamarin.Neo4j.ViewModels;
|
using Xamarin.Neo4j.ViewModels;
|
||||||
|
|
||||||
namespace Xamarin.Neo4j.Pages
|
namespace Xamarin.Neo4j.Pages
|
||||||
@@ -13,11 +14,25 @@ namespace Xamarin.Neo4j.Pages
|
|||||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||||
public partial class QueriesPage : ContentPage
|
public partial class QueriesPage : ContentPage
|
||||||
{
|
{
|
||||||
|
private QueriesViewModel ViewModel => (QueriesViewModel)BindingContext;
|
||||||
|
|
||||||
public QueriesPage()
|
public QueriesPage()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
BindingContext = new QueriesViewModel(Navigation);
|
BindingContext = new QueriesViewModel(Navigation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void OnAppearing()
|
||||||
|
{
|
||||||
|
ViewModel.LoadQueries();
|
||||||
|
|
||||||
|
base.OnAppearing();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void StartSessionWithQuery(object sender, ItemTappedEventArgs e)
|
||||||
|
{
|
||||||
|
ViewModel.StartSession((Query)e.Item);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,5 +7,6 @@
|
|||||||
<TabbedPage.Children>
|
<TabbedPage.Children>
|
||||||
<pages:ConnectionsPage />
|
<pages:ConnectionsPage />
|
||||||
<pages:QueriesPage />
|
<pages:QueriesPage />
|
||||||
|
<pages:SettingsPage />
|
||||||
</TabbedPage.Children>
|
</TabbedPage.Children>
|
||||||
</TabbedPage>
|
</TabbedPage>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||||
xmlns:fonts="clr-namespace:Xamarin.Neo4j.Fonts;assembly=Xamarin.Neo4j"
|
xmlns:fonts="clr-namespace:Xamarin.Neo4j.Fonts;assembly=Xamarin.Neo4j"
|
||||||
xmlns:controls="clr-namespace:Xamarin.Neo4j.Controls;assembly=Xamarin.Neo4j"
|
xmlns:controls="clr-namespace:Xamarin.Neo4j.Controls;assembly=Xamarin.Neo4j"
|
||||||
|
xmlns:pancakeView="clr-namespace:Xamarin.Forms.PancakeView;assembly=Xamarin.Forms.PancakeView"
|
||||||
x:Class="Xamarin.Neo4j.Pages.SessionPage">
|
x:Class="Xamarin.Neo4j.Pages.SessionPage">
|
||||||
<NavigationPage.TitleView>
|
<NavigationPage.TitleView>
|
||||||
<StackLayout Spacing="0">
|
<StackLayout Spacing="0">
|
||||||
@@ -24,17 +25,35 @@
|
|||||||
</StackLayout>
|
</StackLayout>
|
||||||
</NavigationPage.TitleView>
|
</NavigationPage.TitleView>
|
||||||
|
|
||||||
|
<ContentPage.ToolbarItems>
|
||||||
|
<ToolbarItem Command="{Binding Commands[ExecuteQuery]}">
|
||||||
|
<ToolbarItem.IconImageSource>
|
||||||
|
<FontImageSource
|
||||||
|
FontFamily="{StaticResource FontAwesomeSolid}"
|
||||||
|
Glyph="{x:Static fonts:FontAwesomeSolid.Play}" Size="20" />
|
||||||
|
</ToolbarItem.IconImageSource>
|
||||||
|
</ToolbarItem>
|
||||||
|
</ContentPage.ToolbarItems>
|
||||||
|
|
||||||
<ContentPage.Content>
|
<ContentPage.Content>
|
||||||
<StackLayout>
|
<StackLayout>
|
||||||
<controls:QueryBuilder ExecuteQuery="OnExecuteQuery" Query="{Binding Query}" />
|
<pancakeView:PancakeView BackgroundColor="White" CornerRadius="2" Padding="4" Margin="16">
|
||||||
|
<pancakeView:PancakeView CornerRadius="2">
|
||||||
|
<pancakeView:PancakeView.Border>
|
||||||
|
<pancakeView:Border Thickness="2" Color="#d8e5f1" />
|
||||||
|
</pancakeView:PancakeView.Border>
|
||||||
|
|
||||||
<ListView ItemsSource="{Binding QueryResults}">
|
<controls:QueryEditor Text="{Binding Query}" MaxHeight="200" HorizontalOptions="FillAndExpand" AutoSize="TextChanges" />
|
||||||
<ListView.ItemTemplate>
|
</pancakeView:PancakeView>
|
||||||
|
</pancakeView:PancakeView>
|
||||||
|
|
||||||
|
<CollectionView x:Name="resultsCollection" ItemsSource="{Binding QueryResults}">
|
||||||
|
<CollectionView.ItemTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<controls:QueryResultCell />
|
<controls:QueryResultView CloseRequested="CloseResultView" />
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</ListView.ItemTemplate>
|
</CollectionView.ItemTemplate>
|
||||||
</ListView>
|
</CollectionView>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</ContentPage.Content>
|
</ContentPage.Content>
|
||||||
</ContentPage>
|
</ContentPage>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using System.Threading.Tasks;
|
|||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
using Xamarin.Forms.Xaml;
|
using Xamarin.Forms.Xaml;
|
||||||
using Xamarin.Neo4j.Models;
|
using Xamarin.Neo4j.Models;
|
||||||
|
using Xamarin.Neo4j.Utilities;
|
||||||
using Xamarin.Neo4j.ViewModels;
|
using Xamarin.Neo4j.ViewModels;
|
||||||
|
|
||||||
namespace Xamarin.Neo4j.Pages
|
namespace Xamarin.Neo4j.Pages
|
||||||
@@ -16,11 +17,16 @@ namespace Xamarin.Neo4j.Pages
|
|||||||
{
|
{
|
||||||
private SessionViewModel ViewModel => (SessionViewModel) BindingContext;
|
private SessionViewModel ViewModel => (SessionViewModel) BindingContext;
|
||||||
|
|
||||||
public SessionPage(Neo4jConnectionString connectionString)
|
public SessionPage(Neo4jConnectionString connectionString, string initialQuery = null)
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
BindingContext = new SessionViewModel(Navigation, connectionString);
|
BindingContext = new SessionViewModel(Navigation, connectionString, initialQuery);
|
||||||
|
|
||||||
|
MessagingCenter.Subscribe<SessionViewModel>(this, "ResetScroll", (sender) =>
|
||||||
|
{
|
||||||
|
resultsCollection.ScrollTo(0, 0, ScrollToPosition.Start, true);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FocusDatabasePicker(object sender, EventArgs e)
|
private void FocusDatabasePicker(object sender, EventArgs e)
|
||||||
@@ -28,9 +34,9 @@ namespace Xamarin.Neo4j.Pages
|
|||||||
databasePicker.Focus();
|
databasePicker.Focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnExecuteQuery(object sender, EventArgs e)
|
private void CloseResultView(object sender, GenericEventArgs<QueryResult> e)
|
||||||
{
|
{
|
||||||
ViewModel.ExecuteQuery();
|
ViewModel.DeleteQueryResult(e.Data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||||
|
xmlns:fonts="clr-namespace:Xamarin.Neo4j.Fonts;assembly=Xamarin.Neo4j"
|
||||||
|
Title="Settings"
|
||||||
|
x:Class="Xamarin.Neo4j.Pages.SettingsPage">
|
||||||
|
<ContentPage.IconImageSource>
|
||||||
|
<FontImageSource
|
||||||
|
FontFamily="{StaticResource FontAwesomeSolid}"
|
||||||
|
Glyph="{x:Static fonts:FontAwesomeSolid.Cogs}"
|
||||||
|
Size="20" />
|
||||||
|
</ContentPage.IconImageSource>
|
||||||
|
|
||||||
|
<ContentPage.Content>
|
||||||
|
<ScrollView>
|
||||||
|
<StackLayout Spacing="15" Padding="25">
|
||||||
|
<StackLayout Spacing="15" VerticalOptions="EndAndExpand">
|
||||||
|
<Label Text="A product of" HorizontalOptions="Center" FontAttributes="Italic" FontSize="12" TextColor="{StaticResource SecondaryTextColor}" />
|
||||||
|
<Image Source="resoftware.png" HorizontalOptions="Center" WidthRequest="100">
|
||||||
|
<Image.GestureRecognizers>
|
||||||
|
<TapGestureRecognizer Command="{Binding Commands[OpenReSoftwareSite]}" />
|
||||||
|
</Image.GestureRecognizers>
|
||||||
|
</Image>
|
||||||
|
</StackLayout>
|
||||||
|
</StackLayout>
|
||||||
|
</ScrollView>
|
||||||
|
</ContentPage.Content>
|
||||||
|
</ContentPage>
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
using Xamarin.Forms;
|
||||||
|
using Xamarin.Forms.Xaml;
|
||||||
|
using Xamarin.Neo4j.ViewModels;
|
||||||
|
|
||||||
|
namespace Xamarin.Neo4j.Pages
|
||||||
|
{
|
||||||
|
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||||
|
public partial class SettingsPage : ContentPage
|
||||||
|
{
|
||||||
|
public SettingsPage()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
|
BindingContext = new SettingsViewModel(Navigation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||||
|
xmlns:converters="clr-namespace:Xamarin.Neo4j.Converters;assembly=Xamarin.Neo4j"
|
||||||
|
Title="{Binding Title}"
|
||||||
|
x:Class="Xamarin.Neo4j.Pages.TablePage">
|
||||||
|
<ContentPage.Resources>
|
||||||
|
<ResourceDictionary>
|
||||||
|
<converters:JsonConvertConverter x:Key="jsonConvert" />
|
||||||
|
</ResourceDictionary>
|
||||||
|
</ContentPage.Resources>
|
||||||
|
|
||||||
|
<ContentPage.Content>
|
||||||
|
<CarouselView ItemsSource="{Binding Rows}" Position="{Binding Position}" HorizontalScrollBarVisibility="Never" VerticalScrollBarVisibility="Never">
|
||||||
|
<CarouselView.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<CollectionView ItemsSource="{Binding .}">
|
||||||
|
<CollectionView.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<StackLayout Margin="0, 0, 0, 25" Padding="10">
|
||||||
|
<Label Text="{Binding Key, StringFormat='{0}:'}" FontAttributes="Bold" />
|
||||||
|
<Label Text="{Binding Value, Converter={StaticResource jsonConvert}}" FontSize="Small" />
|
||||||
|
</StackLayout>
|
||||||
|
</DataTemplate>
|
||||||
|
</CollectionView.ItemTemplate>
|
||||||
|
</CollectionView>
|
||||||
|
</DataTemplate>
|
||||||
|
</CarouselView.ItemTemplate>
|
||||||
|
</CarouselView>
|
||||||
|
</ContentPage.Content>
|
||||||
|
</ContentPage>
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
using Xamarin.Forms;
|
||||||
|
using Xamarin.Forms.Xaml;
|
||||||
|
using Xamarin.Neo4j.Models;
|
||||||
|
using Xamarin.Neo4j.ViewModels;
|
||||||
|
|
||||||
|
namespace Xamarin.Neo4j.Pages
|
||||||
|
{
|
||||||
|
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||||
|
public partial class TablePage : ContentPage
|
||||||
|
{
|
||||||
|
public TablePage(QueryResult queryResult)
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
|
BindingContext = new TableViewModel(Navigation, queryResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
namespace Xamarin.Neo4j.Services
|
||||||
|
{
|
||||||
|
public interface IScreenSizeService
|
||||||
|
{
|
||||||
|
int GetScreenHeight();
|
||||||
|
|
||||||
|
int GetScreenWidth();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -87,16 +87,21 @@ namespace Xamarin.Neo4j.Services
|
|||||||
|
|
||||||
public async Task<QueryResult> ExecuteQuery(string query, Neo4jConnectionString connectionString)
|
public async Task<QueryResult> ExecuteQuery(string query, Neo4jConnectionString connectionString)
|
||||||
{
|
{
|
||||||
|
var results = new Dictionary<string, List<object>>();
|
||||||
|
|
||||||
|
var canDisplayGraph = false;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var session = GraphClient.Driver.AsyncSession(d => d.WithDatabase(connectionString.Database));
|
var session = GraphClient.Driver.AsyncSession(d => d.WithDatabase(connectionString.Database));
|
||||||
var cursor = await session.RunAsync(query);
|
var cursor = await session.RunAsync(query);
|
||||||
|
|
||||||
var nodes = new List<INode>();
|
|
||||||
var relationships = new List<IRelationship>();
|
|
||||||
|
|
||||||
while (await cursor.FetchAsync())
|
while (await cursor.FetchAsync())
|
||||||
{
|
{
|
||||||
|
foreach (var key in cursor.Current.Keys)
|
||||||
|
if (results.ContainsKey(key) == false)
|
||||||
|
results.Add(key, new List<object>());
|
||||||
|
|
||||||
foreach (var record in cursor.Current.Values)
|
foreach (var record in cursor.Current.Values)
|
||||||
{
|
{
|
||||||
var value = record.Value;
|
var value = record.Value;
|
||||||
@@ -104,11 +109,16 @@ namespace Xamarin.Neo4j.Services
|
|||||||
switch (value)
|
switch (value)
|
||||||
{
|
{
|
||||||
case INode _:
|
case INode _:
|
||||||
nodes.Add(value.As<INode>());
|
canDisplayGraph = true;
|
||||||
|
results[record.Key].Add(value.As<INode>());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IRelationship _:
|
case IRelationship _:
|
||||||
relationships.Add(value.As<IRelationship>());
|
results[record.Key].Add(value.As<IRelationship>());
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
results[record.Key].Add(value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -116,11 +126,12 @@ namespace Xamarin.Neo4j.Services
|
|||||||
|
|
||||||
return new QueryResult()
|
return new QueryResult()
|
||||||
{
|
{
|
||||||
|
Id = Guid.NewGuid(),
|
||||||
Success = true,
|
Success = true,
|
||||||
|
CanDisplayGraph = canDisplayGraph,
|
||||||
Query = query,
|
Query = query,
|
||||||
ConnectionString = connectionString,
|
ConnectionString = connectionString,
|
||||||
Nodes = nodes,
|
Results = results
|
||||||
Relationships = relationships
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,6 +139,7 @@ namespace Xamarin.Neo4j.Services
|
|||||||
{
|
{
|
||||||
return new QueryResult()
|
return new QueryResult()
|
||||||
{
|
{
|
||||||
|
Id = Guid.NewGuid(),
|
||||||
Success = false,
|
Success = false,
|
||||||
Query = query,
|
Query = query,
|
||||||
ConnectionString = connectionString,
|
ConnectionString = connectionString,
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||||
|
x:Class="Xamarin.Neo4j.Themes.DarkTheme">
|
||||||
|
<ResourceDictionary.MergedDictionaries>
|
||||||
|
<ResourceDictionary Source="Fonts.xaml" />
|
||||||
|
</ResourceDictionary.MergedDictionaries>
|
||||||
|
|
||||||
|
<Color x:Key="PageBackground">#545863</Color>
|
||||||
|
<Color x:Key="SecondaryTextColor">#a6a7b2</Color>
|
||||||
|
<Color x:Key="Accent">#31333b</Color>
|
||||||
|
<Color x:Key="QueryTextBackground">Black</Color>
|
||||||
|
<Color x:Key="QueryTextBorder">#686868</Color>
|
||||||
|
<Color x:Key="QueryActionBar">#686868</Color>
|
||||||
|
<Color x:Key="Extreme">Black</Color>
|
||||||
|
|
||||||
|
<Style TargetType="ContentPage" ApplyToDerivedTypes="True">
|
||||||
|
<Setter Property="BackgroundColor" Value="{StaticResource PageBackground}" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style TargetType="ListView">
|
||||||
|
<Setter Property="BackgroundColor" Value="Transparent" />
|
||||||
|
<Setter Property="SeparatorColor" Value="LightGray" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style TargetType="NavigationPage">
|
||||||
|
<Setter Property="BarBackgroundColor" Value="{StaticResource Accent}"/>
|
||||||
|
<Setter Property="BarTextColor" Value="White" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style TargetType="TabbedPage" ApplyToDerivedTypes="True">
|
||||||
|
<Setter Property="BackgroundColor" Value="White"/>
|
||||||
|
<Setter Property="BarTextColor" Value="Black"/>
|
||||||
|
<Setter Property="SelectedTabColor" Value="White"/>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style TargetType="Editor" ApplyToDerivedTypes="True">
|
||||||
|
<Setter Property="BackgroundColor" Value="White"/>
|
||||||
|
<Setter Property="TextColor" Value="Black"/>
|
||||||
|
</Style>
|
||||||
|
</ResourceDictionary>
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
//
|
||||||
|
// DarkTheme_xaml.cs
|
||||||
|
//
|
||||||
|
// Trevi Awater
|
||||||
|
// 14-01-2022
|
||||||
|
//
|
||||||
|
// © Xamarin.Neo4j
|
||||||
|
//
|
||||||
|
|
||||||
|
using Xamarin.Forms;
|
||||||
|
using Xamarin.Forms.Xaml;
|
||||||
|
|
||||||
|
namespace Xamarin.Neo4j.Themes
|
||||||
|
{
|
||||||
|
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||||
|
public partial class DarkTheme : ResourceDictionary
|
||||||
|
{
|
||||||
|
public DarkTheme()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
21
Xamarin.Neo4j/Xamarin.Neo4j/Xamarin.Neo4j/Themes/Fonts.xaml
Normal file
21
Xamarin.Neo4j/Xamarin.Neo4j/Xamarin.Neo4j/Themes/Fonts.xaml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||||
|
x:Class="Xamarin.Neo4j.Themes.Fonts">
|
||||||
|
|
||||||
|
<OnPlatform x:TypeArguments="x:String" x:Key="FontAwesomeBrands">
|
||||||
|
<On Platform="Android" Value="FontAwesome5Brands.ttf#Regular" />
|
||||||
|
<On Platform="iOS" Value="FontAwesome5Brands-Regular" />
|
||||||
|
</OnPlatform>
|
||||||
|
|
||||||
|
<OnPlatform x:TypeArguments="x:String" x:Key="FontAwesomeSolid">
|
||||||
|
<On Platform="Android" Value="FontAwesome5Solid.ttf#Regular" />
|
||||||
|
<On Platform="iOS" Value="FontAwesome5Free-Solid" />
|
||||||
|
</OnPlatform>
|
||||||
|
|
||||||
|
<OnPlatform x:TypeArguments="x:String" x:Key="FontAwesomeRegular">
|
||||||
|
<On Platform="Android" Value="FontAwesome5Regular.ttf#Regular" />
|
||||||
|
<On Platform="iOS" Value="FontAwesome5Free-Regular" />
|
||||||
|
</OnPlatform>
|
||||||
|
</ResourceDictionary>
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
using Xamarin.Forms;
|
||||||
|
using Xamarin.Forms.Xaml;
|
||||||
|
|
||||||
|
namespace Xamarin.Neo4j.Themes
|
||||||
|
{
|
||||||
|
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||||
|
public partial class Fonts : ResourceDictionary
|
||||||
|
{
|
||||||
|
public Fonts()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||||
|
x:Class="Xamarin.Neo4j.Themes.LightTheme">
|
||||||
|
<ResourceDictionary.MergedDictionaries>
|
||||||
|
<ResourceDictionary Source="Fonts.xaml" />
|
||||||
|
</ResourceDictionary.MergedDictionaries>
|
||||||
|
|
||||||
|
<Color x:Key="PageBackground">#e4ecf5</Color>
|
||||||
|
<Color x:Key="SecondaryTextColor">#868a92</Color>
|
||||||
|
<Color x:Key="Accent">#31333b</Color>
|
||||||
|
<Color x:Key="QueryTextBackground">#e0e0e0</Color>
|
||||||
|
<Color x:Key="QueryTextBorder">#31333b</Color>
|
||||||
|
<Color x:Key="QueryActionBar">#31343B</Color>
|
||||||
|
<Color x:Key="Extreme">#FFFFFF</Color>
|
||||||
|
|
||||||
|
<Style TargetType="ContentPage" ApplyToDerivedTypes="True">
|
||||||
|
<Setter Property="BackgroundColor" Value="{StaticResource PageBackground}" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style TargetType="ListView">
|
||||||
|
<Setter Property="BackgroundColor" Value="Transparent" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style TargetType="NavigationPage">
|
||||||
|
<Setter Property="BarBackgroundColor" Value="{StaticResource Accent}"/>
|
||||||
|
<Setter Property="BarTextColor" Value="White" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style TargetType="TabbedPage" ApplyToDerivedTypes="True">
|
||||||
|
<Setter Property="BackgroundColor" Value="White"/>
|
||||||
|
<Setter Property="BarTextColor" Value="Black"/>
|
||||||
|
<Setter Property="SelectedTabColor" Value="{StaticResource Accent}"/>
|
||||||
|
</Style>
|
||||||
|
</ResourceDictionary>
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
using Xamarin.Forms;
|
||||||
|
using Xamarin.Forms.Xaml;
|
||||||
|
|
||||||
|
namespace Xamarin.Neo4j.Themes
|
||||||
|
{
|
||||||
|
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||||
|
public partial class LightTheme : ResourceDictionary
|
||||||
|
{
|
||||||
|
public LightTheme()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
//
|
||||||
|
// GenericEventArgs.cs
|
||||||
|
//
|
||||||
|
// Trevi Awater
|
||||||
|
// 13-01-2022
|
||||||
|
//
|
||||||
|
// © Xamarin.Neo4j
|
||||||
|
//
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Xamarin.Neo4j.Utilities
|
||||||
|
{
|
||||||
|
public class GenericEventArgs<T> : EventArgs
|
||||||
|
{
|
||||||
|
public T Data { get; }
|
||||||
|
|
||||||
|
public GenericEventArgs(T data)
|
||||||
|
{
|
||||||
|
Data = data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using Acr.UserDialogs;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
using Xamarin.Neo4j.Annotations;
|
using Xamarin.Neo4j.Annotations;
|
||||||
using Xamarin.Neo4j.Managers;
|
using Xamarin.Neo4j.Managers;
|
||||||
@@ -40,6 +41,18 @@ namespace Xamarin.Neo4j.ViewModels
|
|||||||
|
|
||||||
LoadConnectionStrings();
|
LoadConnectionStrings();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
Commands.Add("StartSession", new Command(async () =>
|
||||||
|
{
|
||||||
|
if (ConnectionStringManager.ActiveConnectionString == null)
|
||||||
|
{
|
||||||
|
await UserDialogs.Instance.AlertAsync("Please select a connection before starting a session.");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await Navigation.PushAsync(new SessionPage(ConnectionStringManager.ActiveConnectionString));
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
[NotifyPropertyChangedInvocator]
|
[NotifyPropertyChangedInvocator]
|
||||||
@@ -53,6 +66,14 @@ namespace Xamarin.Neo4j.ViewModels
|
|||||||
ConnectionStrings = await ConnectionStringManager.GetConnectionStrings();
|
ConnectionStrings = await ConnectionStringManager.GetConnectionStrings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetActiveConnectionString(Neo4jConnectionString connectionString)
|
||||||
|
{
|
||||||
|
ConnectionStringManager.ActiveConnectionString = ConnectionStringManager.ActiveConnectionString?.Id == connectionString.Id ? null : connectionString;
|
||||||
|
|
||||||
|
// HACK: This causes the Converter to re-execute. This can be done much cleaner.
|
||||||
|
LoadConnectionStrings();
|
||||||
|
}
|
||||||
|
|
||||||
#region Bindable Properties
|
#region Bindable Properties
|
||||||
|
|
||||||
public IEnumerable<Neo4jConnectionString> ConnectionStrings
|
public IEnumerable<Neo4jConnectionString> ConnectionStrings
|
||||||
@@ -63,7 +84,7 @@ namespace Xamarin.Neo4j.ViewModels
|
|||||||
{
|
{
|
||||||
_connectionStrings = value;
|
_connectionStrings = value;
|
||||||
|
|
||||||
OnPropertyChanged();
|
OnPropertyChanged(nameof(ConnectionStrings));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
//
|
||||||
|
// VisualizationViewModel.cs
|
||||||
|
//
|
||||||
|
// Trevi Awater
|
||||||
|
// 10-01-2022
|
||||||
|
//
|
||||||
|
// © Xamarin.Neo4j
|
||||||
|
//
|
||||||
|
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
using Xamarin.Neo4j.Annotations;
|
||||||
|
using Xamarin.Neo4j.Models;
|
||||||
|
|
||||||
|
namespace Xamarin.Neo4j.ViewModels
|
||||||
|
{
|
||||||
|
public class GraphViewModel : ViewModelBase, INotifyPropertyChanged
|
||||||
|
{
|
||||||
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
|
||||||
|
private HtmlWebViewSource _source;
|
||||||
|
|
||||||
|
public GraphViewModel(INavigation navigation, string html) : base(navigation)
|
||||||
|
{
|
||||||
|
Source = new HtmlWebViewSource
|
||||||
|
{
|
||||||
|
Html = html
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[NotifyPropertyChangedInvocator]
|
||||||
|
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||||
|
{
|
||||||
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Bindable Properties
|
||||||
|
|
||||||
|
public HtmlWebViewSource Source
|
||||||
|
{
|
||||||
|
get => _source;
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_source = value;
|
||||||
|
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,10 +7,15 @@
|
|||||||
// © Xamarin.Neo4j
|
// © Xamarin.Neo4j
|
||||||
//
|
//
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using Acr.UserDialogs;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
using Xamarin.Neo4j.Annotations;
|
using Xamarin.Neo4j.Annotations;
|
||||||
|
using Xamarin.Neo4j.Managers;
|
||||||
|
using Xamarin.Neo4j.Models;
|
||||||
|
using Xamarin.Neo4j.Pages;
|
||||||
|
|
||||||
namespace Xamarin.Neo4j.ViewModels
|
namespace Xamarin.Neo4j.ViewModels
|
||||||
{
|
{
|
||||||
@@ -18,9 +23,31 @@ namespace Xamarin.Neo4j.ViewModels
|
|||||||
{
|
{
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
|
||||||
|
private IEnumerable<Query> _queries;
|
||||||
|
|
||||||
public QueriesViewModel(INavigation navigation) : base(navigation)
|
public QueriesViewModel(INavigation navigation) : base(navigation)
|
||||||
{
|
{
|
||||||
|
Commands.Add("DeleteQuery", new Command((o) =>
|
||||||
|
{
|
||||||
|
if (!(o is Query query))
|
||||||
|
return;
|
||||||
|
|
||||||
|
SavedQueryManager.DeleteSavedQuery(query);
|
||||||
|
|
||||||
|
LoadQueries();
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
public async void StartSession(Query query)
|
||||||
|
{
|
||||||
|
if (ConnectionStringManager.ActiveConnectionString == null)
|
||||||
|
{
|
||||||
|
await UserDialogs.Instance.AlertAsync("Please select a connection before starting a session.");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await Navigation.PushAsync(new SessionPage(ConnectionStringManager.ActiveConnectionString, query.QueryText));
|
||||||
}
|
}
|
||||||
|
|
||||||
[NotifyPropertyChangedInvocator]
|
[NotifyPropertyChangedInvocator]
|
||||||
@@ -28,5 +55,26 @@ namespace Xamarin.Neo4j.ViewModels
|
|||||||
{
|
{
|
||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void LoadQueries()
|
||||||
|
{
|
||||||
|
Queries = SavedQueryManager.GetSavedQueries();
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Bindable Properties
|
||||||
|
|
||||||
|
public IEnumerable<Query> Queries
|
||||||
|
{
|
||||||
|
get => _queries;
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_queries = value;
|
||||||
|
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,12 @@ using System.Reflection;
|
|||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using Acr.UserDialogs;
|
using Acr.UserDialogs;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
using Xamarin.Forms.Internals;
|
||||||
using Xamarin.Neo4j.Annotations;
|
using Xamarin.Neo4j.Annotations;
|
||||||
using Xamarin.Neo4j.Models;
|
using Xamarin.Neo4j.Models;
|
||||||
using Xamarin.Neo4j.Pages;
|
using Xamarin.Neo4j.Pages;
|
||||||
using Xamarin.Neo4j.Services;
|
using Xamarin.Neo4j.Services;
|
||||||
|
using Xamarin.Neo4j.Utilities;
|
||||||
|
|
||||||
namespace Xamarin.Neo4j.ViewModels
|
namespace Xamarin.Neo4j.ViewModels
|
||||||
{
|
{
|
||||||
@@ -29,6 +31,8 @@ namespace Xamarin.Neo4j.ViewModels
|
|||||||
|
|
||||||
private readonly Neo4jService _neo4jService;
|
private readonly Neo4jService _neo4jService;
|
||||||
|
|
||||||
|
private readonly IScreenSizeService _screenSizeService;
|
||||||
|
|
||||||
private Database _currentDatabase;
|
private Database _currentDatabase;
|
||||||
|
|
||||||
private List<Database> _availableDatabases;
|
private List<Database> _availableDatabases;
|
||||||
@@ -39,30 +43,36 @@ namespace Xamarin.Neo4j.ViewModels
|
|||||||
|
|
||||||
private string _query;
|
private string _query;
|
||||||
|
|
||||||
public SessionViewModel(INavigation navigation, Neo4jConnectionString connectionString) : base(navigation)
|
public SessionViewModel(INavigation navigation, Neo4jConnectionString connectionString, string initialQuery) : base(navigation)
|
||||||
{
|
{
|
||||||
_connectionString = connectionString;
|
_connectionString = connectionString;
|
||||||
|
|
||||||
_neo4jService = DependencyService.Resolve<Neo4jService>();
|
_neo4jService = DependencyService.Resolve<Neo4jService>();
|
||||||
|
_screenSizeService = DependencyService.Resolve<IScreenSizeService>();
|
||||||
|
|
||||||
|
Query = initialQuery;
|
||||||
QueryResults = new ObservableCollection<QueryResult>();
|
QueryResults = new ObservableCollection<QueryResult>();
|
||||||
|
|
||||||
|
Commands.Add("ExecuteQuery", new Command(async () =>
|
||||||
|
{
|
||||||
|
_connectionString.Database = CurrentDatabase.Name;
|
||||||
|
|
||||||
|
var result = await _neo4jService.ExecuteQuery(Query, _connectionString);
|
||||||
|
|
||||||
|
if (result.Success)
|
||||||
|
{
|
||||||
|
QueryResults.Insert(0, result);
|
||||||
|
|
||||||
|
MessagingCenter.Send(this, "ResetScroll");
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
await UserDialogs.Instance.AlertAsync(result.ErrorMessage);
|
||||||
|
}));
|
||||||
|
|
||||||
InitializeConnection(connectionString);
|
InitializeConnection(connectionString);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void ExecuteQuery()
|
|
||||||
{
|
|
||||||
_connectionString.Database = CurrentDatabase.Name;
|
|
||||||
|
|
||||||
var result = await _neo4jService.ExecuteQuery(Query, _connectionString);
|
|
||||||
|
|
||||||
if (result.Success)
|
|
||||||
QueryResults.Add(result);
|
|
||||||
|
|
||||||
else
|
|
||||||
UserDialogs.Instance.Alert(result.ErrorMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void InitializeConnection(Neo4jConnectionString connectionString)
|
private async void InitializeConnection(Neo4jConnectionString connectionString)
|
||||||
{
|
{
|
||||||
await _neo4jService.EstablishConnection(connectionString);
|
await _neo4jService.EstablishConnection(connectionString);
|
||||||
@@ -76,6 +86,13 @@ namespace Xamarin.Neo4j.ViewModels
|
|||||||
CurrentDatabase = AvailableDatabases.Single(ad => ad.Default);
|
CurrentDatabase = AvailableDatabases.Single(ad => ad.Default);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void DeleteQueryResult(QueryResult queryResult)
|
||||||
|
{
|
||||||
|
var index = QueryResults.IndexOf(qr => qr.Id == queryResult.Id);
|
||||||
|
|
||||||
|
QueryResults.RemoveAt(index);
|
||||||
|
}
|
||||||
|
|
||||||
[NotifyPropertyChangedInvocator]
|
[NotifyPropertyChangedInvocator]
|
||||||
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
//
|
||||||
|
// SettingsViewModel.cs
|
||||||
|
//
|
||||||
|
// Trevi Awater
|
||||||
|
// 13-01-2022
|
||||||
|
//
|
||||||
|
// © Xamarin.Neo4j
|
||||||
|
//
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using Xamarin.Essentials;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
using Xamarin.Neo4j.Annotations;
|
||||||
|
|
||||||
|
namespace Xamarin.Neo4j.ViewModels
|
||||||
|
{
|
||||||
|
public class SettingsViewModel : ViewModelBase, INotifyPropertyChanged
|
||||||
|
{
|
||||||
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
|
||||||
|
public SettingsViewModel(INavigation navigation) : base(navigation)
|
||||||
|
{
|
||||||
|
Commands.Add("OpenReSoftwareSite", new Command(async () =>
|
||||||
|
{
|
||||||
|
await Launcher.OpenAsync(new Uri("https://resoftware.nl/"));
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
[NotifyPropertyChangedInvocator]
|
||||||
|
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||||
|
{
|
||||||
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
//
|
||||||
|
// TableViewModel.cs
|
||||||
|
//
|
||||||
|
// Trevi Awater
|
||||||
|
// 13-01-2022
|
||||||
|
//
|
||||||
|
// © Xamarin.Neo4j
|
||||||
|
//
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
using Xamarin.Neo4j.Annotations;
|
||||||
|
using Xamarin.Neo4j.Models;
|
||||||
|
|
||||||
|
namespace Xamarin.Neo4j.ViewModels
|
||||||
|
{
|
||||||
|
public class TableViewModel : ViewModelBase, INotifyPropertyChanged
|
||||||
|
{
|
||||||
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
|
||||||
|
private IEnumerable<List<KeyValuePair<string, object>>> _rows;
|
||||||
|
|
||||||
|
private int _position;
|
||||||
|
|
||||||
|
public TableViewModel(INavigation navigation, QueryResult queryResult) : base(navigation)
|
||||||
|
{
|
||||||
|
var headers = queryResult.Results.Keys;
|
||||||
|
var transposed = Transpose(queryResult.Results.Select(a => a.Value.ToArray()).ToArray());
|
||||||
|
|
||||||
|
Rows = transposed.Select(row => row.Select((t, i) => new KeyValuePair<string, object>(headers.ElementAt(i), t)).ToList()).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IEnumerable<T[]> Transpose<T>(T[][] arr)
|
||||||
|
{
|
||||||
|
var rowCount = arr.Length;
|
||||||
|
var columnCount = arr[0].Length;
|
||||||
|
var transposed = new T[columnCount][];
|
||||||
|
|
||||||
|
if (rowCount == columnCount)
|
||||||
|
{
|
||||||
|
transposed = (T[][])arr.Clone();
|
||||||
|
|
||||||
|
for (var i = 1; i < rowCount; i++)
|
||||||
|
for (var j = 0; j < i; j++)
|
||||||
|
(transposed[i][j], transposed[j][i]) = (transposed[j][i], transposed[i][j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
for (var column = 0; column < columnCount; column++)
|
||||||
|
{
|
||||||
|
transposed[column] = new T[rowCount];
|
||||||
|
|
||||||
|
for (var row = 0; row < rowCount; row++)
|
||||||
|
transposed[column][row] = arr[row][column];
|
||||||
|
}
|
||||||
|
|
||||||
|
return transposed;
|
||||||
|
}
|
||||||
|
|
||||||
|
[NotifyPropertyChangedInvocator]
|
||||||
|
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||||
|
{
|
||||||
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Bindable Properties
|
||||||
|
|
||||||
|
public IEnumerable<List<KeyValuePair<string, object>>> Rows
|
||||||
|
{
|
||||||
|
get => _rows;
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_rows = value;
|
||||||
|
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Position
|
||||||
|
{
|
||||||
|
get => _position;
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_position = value;
|
||||||
|
|
||||||
|
OnPropertyChanged(nameof(Position));
|
||||||
|
OnPropertyChanged(nameof(Title));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Title => $"{Position + 1}/{Rows.Count()}";
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
//
|
|
||||||
// VisualizationViewModel.cs
|
|
||||||
//
|
|
||||||
// Trevi Awater
|
|
||||||
// 10-01-2022
|
|
||||||
//
|
|
||||||
// © Xamarin.Neo4j
|
|
||||||
//
|
|
||||||
|
|
||||||
using System.ComponentModel;
|
|
||||||
using System.IO;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using Xamarin.Forms;
|
|
||||||
using Xamarin.Neo4j.Annotations;
|
|
||||||
using Xamarin.Neo4j.Models;
|
|
||||||
|
|
||||||
namespace Xamarin.Neo4j.ViewModels
|
|
||||||
{
|
|
||||||
public class VisualizationViewModel : ViewModelBase, INotifyPropertyChanged
|
|
||||||
{
|
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
|
||||||
|
|
||||||
private HtmlWebViewSource _source;
|
|
||||||
|
|
||||||
public VisualizationViewModel(INavigation navigation, QueryResult queryResult) : base(navigation)
|
|
||||||
{
|
|
||||||
ParseNeovisHtml(queryResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ParseNeovisHtml(QueryResult queryResult)
|
|
||||||
{
|
|
||||||
var assembly = Assembly.GetExecutingAssembly();
|
|
||||||
var resourceName = "Xamarin.Neo4j.Visualization.neovis.html";
|
|
||||||
|
|
||||||
using (var stream = assembly.GetManifestResourceStream(resourceName))
|
|
||||||
using (var reader = new StreamReader(stream))
|
|
||||||
{
|
|
||||||
var result = reader.ReadToEnd();
|
|
||||||
|
|
||||||
result = result.Replace("{{host}}", queryResult.ConnectionString.Host);
|
|
||||||
result = result.Replace("{{port}}", queryResult.ConnectionString.Port.ToString());
|
|
||||||
result = result.Replace("{{database}}", queryResult.ConnectionString.Database);
|
|
||||||
result = result.Replace("{{username}}", queryResult.ConnectionString.Username);
|
|
||||||
result = result.Replace("{{password}}", queryResult.ConnectionString.Password);
|
|
||||||
result = result.Replace("{{encryption}}", queryResult.ConnectionString.Encrypted ? "ENCRYPTION_ON" : "ENCRYPTION_OFF");
|
|
||||||
result = result.Replace("{{query}}", queryResult.Query);
|
|
||||||
|
|
||||||
Source = new HtmlWebViewSource
|
|
||||||
{
|
|
||||||
Html = result
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[NotifyPropertyChangedInvocator]
|
|
||||||
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
|
||||||
{
|
|
||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Bindable Properties
|
|
||||||
|
|
||||||
public HtmlWebViewSource Source
|
|
||||||
{
|
|
||||||
get => _source;
|
|
||||||
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_source = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,41 +1,46 @@
|
|||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html>
|
<html lang="en-US">
|
||||||
<head>
|
<head>
|
||||||
<title>Neovis.js Simple Example</title>
|
<title>Graph</title>
|
||||||
|
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
html, body {
|
html, body {
|
||||||
font: 16pt arial;
|
font: 16pt arial;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
height: 100%;
|
||||||
|
background-color: {{backgroundColor}};
|
||||||
}
|
}
|
||||||
|
|
||||||
#viz {
|
#viz {
|
||||||
width: 100vw;
|
width: 100%;
|
||||||
height: 100vh;
|
height: 100%;
|
||||||
border: 1px solid lightgray;
|
|
||||||
font: 22pt arial;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script src="https://cdn.neo4jlabs.com/neovis.js/v1.5.0/neovis.js"></script>
|
<script src="https://cdn.neo4jlabs.com/neovis.js/v1.5.0/neovis.js"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body onload="draw()">
|
<body onload="draw()">
|
||||||
<div id="viz"></div>
|
<div id="viz"></div>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
let viz;
|
||||||
|
|
||||||
|
function draw() {
|
||||||
|
const config = {
|
||||||
|
container_id: "viz",
|
||||||
|
server_url: `bolt://{{host}}:{{port}}`,
|
||||||
|
server_user: `{{username}}`,
|
||||||
|
server_database: `{{database}}`,
|
||||||
|
server_password: `{{password}}`,
|
||||||
|
encrypted: `{{encryption}}`,
|
||||||
|
initial_cypher: `{{query}}`
|
||||||
|
};
|
||||||
|
|
||||||
|
viz = new NeoVis.default(config);
|
||||||
|
viz.render();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
var viz;
|
|
||||||
|
|
||||||
function draw() {
|
|
||||||
var config = {
|
|
||||||
container_id: "viz",
|
|
||||||
server_url: "bolt://{{host}}:{{port}}",
|
|
||||||
server_user: "{{username}}",
|
|
||||||
server_database: "{{database}}",
|
|
||||||
server_password: "{{password}}",
|
|
||||||
encrypted: "{{encryption}}",
|
|
||||||
initial_cypher: "{{query}}"
|
|
||||||
};
|
|
||||||
|
|
||||||
viz = new NeoVis.default(config);
|
|
||||||
viz.render();
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
|
<LangVersion>latest</LangVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||||
@@ -17,10 +18,6 @@
|
|||||||
<PackageReference Include="Xamarin.Forms.PancakeView" Version="2.3.0.759" />
|
<PackageReference Include="Xamarin.Forms.PancakeView" Version="2.3.0.759" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Folder Include="Converters" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Remove="Visualization\neovis.html" />
|
<None Remove="Visualization\neovis.html" />
|
||||||
<EmbeddedResource Include="Visualization\neovis.html" />
|
<EmbeddedResource Include="Visualization\neovis.html" />
|
||||||
|
|||||||
Reference in New Issue
Block a user