├── .gitignore ├── NuGet.Config ├── README.md ├── build ├── App_Data │ └── db.sqlite ├── build-core.proj ├── build.bat ├── build.proj ├── build.tasks └── sync.bat ├── img ├── custom-content-types.png ├── customize-columns.png ├── filter-autoquery-services.png ├── metadata-plugin-link.png ├── multiple-conditions.png ├── paging-queries.png ├── query-default-values-markup.png ├── query-default-values.png ├── search-as-type.png └── unannotated-autoquery-services.png ├── src ├── Directory.Build.props ├── ServiceStack.Admin.Core.sln ├── ServiceStack.Admin.Web │ ├── AppHost.cs │ ├── App_Data │ │ └── db.sqlite │ ├── GitHubQuery.cs │ ├── Global.asax │ ├── Global.asax.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── ServiceStack.Admin.Web.csproj │ ├── StackOverflowQuery.cs │ ├── Web.Debug.config │ ├── Web.Release.config │ ├── Web.config │ ├── dist │ │ ├── app.bundle.js │ │ ├── img │ │ │ ├── MaterialIcons-Regular.eot │ │ │ ├── MaterialIcons-Regular.ttf │ │ │ ├── MaterialIcons-Regular.woff │ │ │ ├── MaterialIcons-Regular.woff2 │ │ │ ├── octicons.ttf │ │ │ ├── octicons.woff │ │ │ ├── roboto-v15-latin-regular.woff │ │ │ └── roboto-v15-latin-regular.woff2 │ │ └── vendor.bundle.js │ ├── gulpfile.js │ ├── index.html │ ├── index.template.ejs │ ├── package-lock.json │ ├── package.json │ ├── requestlogs │ │ └── 2016-04 │ │ │ ├── 2016-04-11-errors.csv │ │ │ ├── 2016-04-11.csv │ │ │ ├── 2016-04-12-errors.csv │ │ │ ├── 2016-04-12.csv │ │ │ ├── 2016-04-13-errors.csv │ │ │ └── 2016-04-13.csv │ ├── src │ │ ├── AutoQuery.tsx │ │ ├── ColumnPrefsDialog.tsx │ │ ├── Content.tsx │ │ ├── Header.tsx │ │ ├── Results.tsx │ │ ├── Sidebar.tsx │ │ ├── app.css │ │ ├── app.tsx │ │ ├── assets │ │ │ └── img │ │ │ │ ├── iconfont │ │ │ │ ├── MaterialIcons-Regular.eot │ │ │ │ ├── MaterialIcons-Regular.ijmap │ │ │ │ ├── MaterialIcons-Regular.svg │ │ │ │ ├── MaterialIcons-Regular.ttf │ │ │ │ ├── MaterialIcons-Regular.woff │ │ │ │ ├── MaterialIcons-Regular.woff2 │ │ │ │ ├── codepoints │ │ │ │ └── material-icons.css │ │ │ │ ├── logo.png │ │ │ │ ├── octicon │ │ │ │ ├── octicon.css │ │ │ │ ├── octicons.ttf │ │ │ │ └── octicons.woff │ │ │ │ └── roboto │ │ │ │ ├── Roboto-Regular.ttf │ │ │ │ ├── roboto-v15-latin-regular.woff │ │ │ │ └── roboto-v15-latin-regular.woff2 │ │ ├── shared.tsx │ │ └── test.fileMock.js │ ├── tsconfig.json │ ├── webpack.config.js │ ├── wwwroot │ │ ├── dist │ │ │ ├── app.bundle.js │ │ │ ├── app.bundle.js.map │ │ │ ├── app.css │ │ │ ├── app.css.map │ │ │ ├── img │ │ │ │ ├── MaterialIcons-Regular.eot │ │ │ │ ├── MaterialIcons-Regular.ttf │ │ │ │ ├── MaterialIcons-Regular.woff │ │ │ │ ├── MaterialIcons-Regular.woff2 │ │ │ │ ├── octicons.ttf │ │ │ │ ├── octicons.woff │ │ │ │ ├── roboto-v15-latin-regular.woff │ │ │ │ └── roboto-v15-latin-regular.woff2 │ │ │ ├── vendor.bundle.js │ │ │ └── vendor.bundle.js.map │ │ └── index.html │ └── wwwroot_build │ │ ├── README.txt │ │ ├── deploy │ │ └── appsettings.txt │ │ └── package-and-deploy.bat ├── ServiceStack.Admin.lite.sln ├── ServiceStack.Admin.sln ├── ServiceStack.Admin │ ├── .vscode │ │ ├── launch.json │ │ └── tasks.json │ ├── AdminFeature.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── ServiceStack.Admin.Core.csproj │ ├── ServiceStack.Admin.Source.csproj │ ├── ServiceStack.Admin.csproj │ └── ss_admin │ │ ├── dist │ │ ├── app.bundle.js │ │ ├── app.bundle.js.map │ │ ├── app.css │ │ ├── app.css.map │ │ ├── img │ │ │ ├── MaterialIcons-Regular.eot │ │ │ ├── MaterialIcons-Regular.ttf │ │ │ ├── MaterialIcons-Regular.woff │ │ │ ├── MaterialIcons-Regular.woff2 │ │ │ ├── octicons.ttf │ │ │ ├── octicons.woff │ │ │ ├── roboto-v15-latin-regular.woff │ │ │ └── roboto-v15-latin-regular.woff2 │ │ ├── vendor.bundle.js │ │ └── vendor.bundle.js.map │ │ └── index.html └── servicestack.snk └── tests ├── Admin.Tasks ├── Admin.Tasks.csproj ├── Config.cs ├── GitHubTasks.cs ├── Properties │ └── AssemblyInfo.cs ├── StackOverflowTasks.cs ├── app.config └── packages.config ├── Directory.Build.props ├── TestSelfHost ├── App.config ├── GitHubQuery.cs ├── Program.cs ├── Properties │ └── AssemblyInfo.cs ├── StackOverflowQuery.cs ├── TestSelfHost.csproj ├── db.sqlite └── packages.config ├── TestVirtualWebHost ├── App_Data │ └── db.sqlite ├── GitHubQuery.cs ├── Global.asax ├── Global.asax.cs ├── Properties │ └── AssemblyInfo.cs ├── StackOverflowQuery.cs ├── TestVirtualWebHost.csproj ├── Web.Debug.config ├── Web.Release.config ├── Web.config └── packages.config └── global.json /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # npm + jspm 5 | node_modules/ 6 | jspm_packages/ 7 | 8 | # User-specific files 9 | *.suo 10 | *.user 11 | *.userosscache 12 | *.sln.docstates 13 | .idea/ 14 | 15 | # User-specific files (MonoDevelop/Xamarin Studio) 16 | *.userprefs 17 | 18 | # Build results 19 | [Dd]ebug/ 20 | [Dd]ebugPublic/ 21 | [Rr]elease/ 22 | [Rr]eleases/ 23 | x64/ 24 | x86/ 25 | bld/ 26 | [Bb]in/ 27 | [Oo]bj/ 28 | 29 | # Visual Studio 2015 cache/options directory 30 | .vs/ 31 | # Uncomment if you have tasks that create the project's static files in wwwroot 32 | #wwwroot/ 33 | 34 | # MSTest test Results 35 | [Tt]est[Rr]esult*/ 36 | [Bb]uild[Ll]og.* 37 | 38 | # NUNIT 39 | *.VisualState.xml 40 | TestResult.xml 41 | 42 | # Build Results of an ATL Project 43 | [Dd]ebugPS/ 44 | [Rr]eleasePS/ 45 | dlldata.c 46 | 47 | # DNX 48 | project.lock.json 49 | artifacts/ 50 | 51 | *_i.c 52 | *_p.c 53 | *_i.h 54 | *.ilk 55 | *.meta 56 | *.obj 57 | *.pch 58 | *.pdb 59 | *.pgc 60 | *.pgd 61 | *.rsp 62 | *.sbr 63 | *.tlb 64 | *.tli 65 | *.tlh 66 | *.tmp 67 | *.tmp_proj 68 | *.log 69 | *.vspscc 70 | *.vssscc 71 | .builds 72 | *.pidb 73 | *.svclog 74 | *.scc 75 | 76 | # Chutzpah Test files 77 | _Chutzpah* 78 | 79 | # Visual C++ cache files 80 | ipch/ 81 | *.aps 82 | *.ncb 83 | *.opendb 84 | *.opensdf 85 | *.sdf 86 | *.cachefile 87 | 88 | # Visual Studio profiler 89 | *.psess 90 | *.vsp 91 | *.vspx 92 | *.sap 93 | 94 | # TFS 2012 Local Workspace 95 | $tf/ 96 | 97 | # Guidance Automation Toolkit 98 | *.gpState 99 | 100 | # ReSharper is a .NET coding add-in 101 | _ReSharper*/ 102 | *.[Rr]e[Ss]harper 103 | *.DotSettings.user 104 | 105 | # JustCode is a .NET coding add-in 106 | .JustCode 107 | 108 | # TeamCity is a build add-in 109 | _TeamCity* 110 | 111 | # DotCover is a Code Coverage Tool 112 | *.dotCover 113 | 114 | # NCrunch 115 | _NCrunch_* 116 | .*crunch*.local.xml 117 | nCrunchTemp_* 118 | 119 | # MightyMoose 120 | *.mm.* 121 | AutoTest.Net/ 122 | 123 | # Web workbench (sass) 124 | .sass-cache/ 125 | 126 | # Installshield output folder 127 | [Ee]xpress/ 128 | 129 | # DocProject is a documentation generator add-in 130 | DocProject/buildhelp/ 131 | DocProject/Help/*.HxT 132 | DocProject/Help/*.HxC 133 | DocProject/Help/*.hhc 134 | DocProject/Help/*.hhk 135 | DocProject/Help/*.hhp 136 | DocProject/Help/Html2 137 | DocProject/Help/html 138 | 139 | # Click-Once directory 140 | publish/ 141 | 142 | # Publish Web Output 143 | *.[Pp]ublish.xml 144 | *.azurePubxml 145 | # TODO: Comment the next line if you want to checkin your web deploy settings 146 | # but database connection strings (with potential passwords) will be unencrypted 147 | *.pubxml 148 | *.publishproj 149 | 150 | # NuGet Packages 151 | *.nupkg 152 | # The packages folder can be ignored because of Package Restore 153 | **/packages/* 154 | # except build/, which is used as an MSBuild target. 155 | !**/packages/build/ 156 | # Uncomment if necessary however generally it will be regenerated when needed 157 | #!**/packages/repositories.config 158 | # NuGet v3's project.json files produces more ignoreable files 159 | *.nuget.props 160 | *.nuget.targets 161 | 162 | # Microsoft Azure Build Output 163 | csx/ 164 | *.build.csdef 165 | 166 | # Microsoft Azure Emulator 167 | ecf/ 168 | rcf/ 169 | 170 | # Microsoft Azure ApplicationInsights config file 171 | ApplicationInsights.config 172 | 173 | # Windows Store app package directory 174 | AppPackages/ 175 | BundleArtifacts/ 176 | 177 | # Visual Studio cache files 178 | # files ending in .cache can be ignored 179 | *.[Cc]ache 180 | # but keep track of directories ending in .cache 181 | !*.[Cc]ache/ 182 | 183 | # Others 184 | ClientBin/ 185 | ~$* 186 | *~ 187 | *.dbmdl 188 | *.dbproj.schemaview 189 | *.publishsettings 190 | node_modules/ 191 | orleans.codegen.cs 192 | 193 | # RIA/Silverlight projects 194 | Generated_Code/ 195 | 196 | # Backup & report files from converting an old project file 197 | # to a newer Visual Studio version. Backup files are not needed, 198 | # because we have git ;-) 199 | _UpgradeReport_Files/ 200 | Backup*/ 201 | UpgradeLog*.XML 202 | UpgradeLog*.htm 203 | 204 | # SQL Server files 205 | *.mdf 206 | *.ldf 207 | 208 | # Business Intelligence projects 209 | *.rdl.data 210 | *.bim.layout 211 | *.bim_*.settings 212 | 213 | # Microsoft Fakes 214 | FakesAssemblies/ 215 | 216 | # GhostDoc plugin setting file 217 | *.GhostDoc.xml 218 | 219 | # Node.js Tools for Visual Studio 220 | .ntvs_analysis.dat 221 | 222 | # Visual Studio 6 build log 223 | *.plg 224 | 225 | # Visual Studio 6 workspace options file 226 | *.opt 227 | 228 | # Visual Studio LightSwitch build output 229 | **/*.HTMLClient/GeneratedArtifacts 230 | **/*.DesktopClient/GeneratedArtifacts 231 | **/*.DesktopClient/ModelManifest.xml 232 | **/*.Server/GeneratedArtifacts 233 | **/*.Server/ModelManifest.xml 234 | _Pvt_Extensions 235 | 236 | # Paket dependency manager 237 | .paket/paket.exe 238 | 239 | # FAKE - F# Make 240 | .fake/ 241 | src/ServiceStack.Admin.WebHost/src/*.map 242 | src/ServiceStack.Admin.WebHost/src/*.js 243 | -------------------------------------------------------------------------------- /NuGet.Config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /build/App_Data/db.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ServiceStack/Admin/d6dda10b17761d109781d167b5da175d33126f53/build/App_Data/db.sqlite -------------------------------------------------------------------------------- /build/build-core.proj: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 6 8 | 0 9 | $(BUILD_NUMBER) 10 | 11 | 12 | 13 | $(MSBuildProjectDirectory)/.. 14 | $(BuildSolutionDir)/src 15 | Release 16 | $(BuildSolutionDir)/NuGet/ 17 | $(MajorVersion).$(MinorVersion).$(PatchVersion) 18 | 19 | 20 | 21 | 22 | BeforeBuildSolutions; 23 | BuildSolutions 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | <Version>[^<]* 50 | <Version>$(PackageVersion) 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /build/build.bat: -------------------------------------------------------------------------------- 1 | SET MSBUILD="C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe" 2 | 3 | %MSBUILD% build.proj /property:Configuration=Release;MinorVersion=7;PatchVersion=1 4 | -------------------------------------------------------------------------------- /build/build.proj: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 6 8 | 0 9 | $(BUILD_NUMBER) 10 | 11 | 12 | 13 | $(MSBuildProjectDirectory)/.. 14 | $(BuildSolutionDir)/src 15 | Release 16 | $(BuildSolutionDir)/NuGet/ 17 | $(MajorVersion).$(MinorVersion).$(PatchVersion) 18 | 19 | 20 | 21 | 22 | BeforeBuildSolutions; 23 | BuildSolutions 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | <Version>[^<]* 49 | <Version>$(PackageVersion) 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /build/build.tasks: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /build/sync.bat: -------------------------------------------------------------------------------- 1 | PUSHD ..\src\ServiceStack.Admin.Web 2 | 3 | COPY GitHubQuery.cs ..\..\tests\TestSelfHost 4 | COPY GitHubQuery.cs ..\..\tests\TestWebHost 5 | COPY StackOverflowQuery.cs ..\..\tests\TestSelfHost 6 | COPY StackOverflowQuery.cs ..\..\tests\TestWebHost 7 | COPY App_Data\db.sqlite ..\..\tests\TestSelfHost 8 | COPY App_Data\db.sqlite ..\..\tests\TestWebHost\App_Data 9 | 10 | RMDIR ..\ServiceStack.Admin\ss_admin /s /q 11 | XCOPY /E wwwroot ..\ServiceStack.Admin\ss_admin\ 12 | 13 | POPD 14 | 15 | msbuild /p:Configuration=Release ..\src\ServiceStack.Admin.sln 16 | -------------------------------------------------------------------------------- /img/custom-content-types.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ServiceStack/Admin/d6dda10b17761d109781d167b5da175d33126f53/img/custom-content-types.png -------------------------------------------------------------------------------- /img/customize-columns.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ServiceStack/Admin/d6dda10b17761d109781d167b5da175d33126f53/img/customize-columns.png -------------------------------------------------------------------------------- /img/filter-autoquery-services.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ServiceStack/Admin/d6dda10b17761d109781d167b5da175d33126f53/img/filter-autoquery-services.png -------------------------------------------------------------------------------- /img/metadata-plugin-link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ServiceStack/Admin/d6dda10b17761d109781d167b5da175d33126f53/img/metadata-plugin-link.png -------------------------------------------------------------------------------- /img/multiple-conditions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ServiceStack/Admin/d6dda10b17761d109781d167b5da175d33126f53/img/multiple-conditions.png -------------------------------------------------------------------------------- /img/paging-queries.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ServiceStack/Admin/d6dda10b17761d109781d167b5da175d33126f53/img/paging-queries.png -------------------------------------------------------------------------------- /img/query-default-values-markup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ServiceStack/Admin/d6dda10b17761d109781d167b5da175d33126f53/img/query-default-values-markup.png -------------------------------------------------------------------------------- /img/query-default-values.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ServiceStack/Admin/d6dda10b17761d109781d167b5da175d33126f53/img/query-default-values.png -------------------------------------------------------------------------------- /img/search-as-type.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ServiceStack/Admin/d6dda10b17761d109781d167b5da175d33126f53/img/search-as-type.png -------------------------------------------------------------------------------- /img/unannotated-autoquery-services.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ServiceStack/Admin/d6dda10b17761d109781d167b5da175d33126f53/img/unannotated-autoquery-services.png -------------------------------------------------------------------------------- /src/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6.0.3 5 | ServiceStack 6 | ServiceStack, Inc. 7 | © 2008-2022 ServiceStack, Inc 8 | true 9 | https://github.com/ServiceStack/Admin 10 | https://servicestack.net/terms 11 | https://servicestack.net/img/logo-64.png 12 | https://docs.servicestack.net/release-notes-history 13 | git 14 | https://github.com/ServiceStack/Admin.git 15 | embedded 16 | latest 17 | true 18 | true 19 | false 20 | 21 | 22 | 23 | true 24 | true 25 | 26 | 27 | 28 | $(DefineConstants);NETFX;NET45;NET472 29 | True 30 | False 31 | ../servicestack.snk 32 | 33 | 34 | 35 | $(DefineConstants);NETSTANDARD;NETSTANDARD2_0 36 | 37 | 38 | 39 | $(DefineConstants);NET6_0;NET6_0_OR_GREATER 40 | 41 | 42 | 43 | $(DefineConstants);NETCORE;NETCORE_SUPPORT 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | DEBUG 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /src/ServiceStack.Admin.Core.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26403.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{3CC4ADC8-802D-4289-8FC2-3A5D5A6145CD}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{6543B24E-7A67-431C-AEC3-61311F906D11}" 9 | ProjectSection(SolutionItems) = preProject 10 | ..\tests\global.json = ..\tests\global.json 11 | EndProjectSection 12 | EndProject 13 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestNetCore", "..\tests\TestNetCore\TestNetCore.csproj", "{27F9D195-AE30-409F-ACB9-9F31C36A146A}" 14 | EndProject 15 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceStack.Admin", "ServiceStack.Admin\ServiceStack.Admin.csproj", "{7964DBBF-7E3B-4B25-9536-11962875BFB6}" 16 | EndProject 17 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceStack.Admin.Signed", "ServiceStack.Admin\ServiceStack.Admin.Signed.csproj", "{C926D481-C552-494A-8A85-1F0270BCE4C8}" 18 | EndProject 19 | Global 20 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 21 | Debug|Any CPU = Debug|Any CPU 22 | Release|Any CPU = Release|Any CPU 23 | EndGlobalSection 24 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 25 | {27F9D195-AE30-409F-ACB9-9F31C36A146A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 26 | {27F9D195-AE30-409F-ACB9-9F31C36A146A}.Debug|Any CPU.Build.0 = Debug|Any CPU 27 | {27F9D195-AE30-409F-ACB9-9F31C36A146A}.Release|Any CPU.ActiveCfg = Release|Any CPU 28 | {27F9D195-AE30-409F-ACB9-9F31C36A146A}.Release|Any CPU.Build.0 = Release|Any CPU 29 | {7964DBBF-7E3B-4B25-9536-11962875BFB6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 30 | {7964DBBF-7E3B-4B25-9536-11962875BFB6}.Debug|Any CPU.Build.0 = Debug|Any CPU 31 | {7964DBBF-7E3B-4B25-9536-11962875BFB6}.Release|Any CPU.ActiveCfg = Release|Any CPU 32 | {7964DBBF-7E3B-4B25-9536-11962875BFB6}.Release|Any CPU.Build.0 = Release|Any CPU 33 | {C926D481-C552-494A-8A85-1F0270BCE4C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 34 | {C926D481-C552-494A-8A85-1F0270BCE4C8}.Debug|Any CPU.Build.0 = Debug|Any CPU 35 | {C926D481-C552-494A-8A85-1F0270BCE4C8}.Release|Any CPU.ActiveCfg = Release|Any CPU 36 | {C926D481-C552-494A-8A85-1F0270BCE4C8}.Release|Any CPU.Build.0 = Release|Any CPU 37 | EndGlobalSection 38 | GlobalSection(SolutionProperties) = preSolution 39 | HideSolutionNode = FALSE 40 | EndGlobalSection 41 | GlobalSection(NestedProjects) = preSolution 42 | {27F9D195-AE30-409F-ACB9-9F31C36A146A} = {3CC4ADC8-802D-4289-8FC2-3A5D5A6145CD} 43 | EndGlobalSection 44 | EndGlobal 45 | -------------------------------------------------------------------------------- /src/ServiceStack.Admin.Web/AppHost.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Funq; 4 | using ServiceStack.Data; 5 | using ServiceStack.OrmLite; 6 | 7 | namespace ServiceStack.Admin.Web 8 | { 9 | public class AppHost : AppHostBase 10 | { 11 | public AppHost() 12 | : base("Admin UI", typeof(AutoQueryServices).Assembly) { } 13 | 14 | public override void Configure(Container container) 15 | { 16 | container.Register(c => 17 | new OrmLiteConnectionFactory("~/App_Data/db.sqlite".MapHostAbsolutePath(), SqliteDialect.Provider)); 18 | 19 | Plugins.Add(new AutoQueryFeature { MaxLimit = 100 }); 20 | 21 | Plugins.Add(new AutoQueryDataFeature { MaxLimit = 100 }); 22 | } 23 | } 24 | 25 | 26 | [FallbackRoute("/{PathInfo*}")] 27 | public class FallbackForClientRoutes 28 | { 29 | public string PathInfo { get; set; } 30 | } 31 | 32 | public class AutoQueryServices : Service 33 | { 34 | public object Any(FallbackForClientRoutes request) 35 | { 36 | return new HttpResult(VirtualFileSources.GetFile("index.html")); 37 | } 38 | } 39 | 40 | 41 | [Route("/query/requestlogs")] 42 | [Route("/query/requestlogs/{Date}")] 43 | public class QueryRequestLogs : QueryData 44 | { 45 | public DateTime? Date { get; set; } 46 | public bool ViewErrors { get; set; } 47 | } 48 | 49 | public class AutoQueryDataServices : Service 50 | { 51 | public IAutoQueryData AutoQuery { get; set; } 52 | 53 | public object Any(QueryRequestLogs query) 54 | { 55 | var date = query.Date.GetValueOrDefault(new DateTime(2016, 4, 13)); 56 | var logSuffix = query.ViewErrors ? "-errors" : ""; 57 | var csvLogsFile = VirtualFileSources.GetFile("requestlogs/{0}-{1}/{0}-{1}-{2}{3}.csv".Fmt( 58 | date.Year.ToString("0000"), 59 | date.Month.ToString("00"), 60 | date.Day.ToString("00"), 61 | logSuffix)); 62 | 63 | if (csvLogsFile == null) 64 | throw HttpError.NotFound("No logs found on " + date.ToShortDateString()); 65 | 66 | var logs = csvLogsFile.ReadAllText().FromCsv>(); 67 | 68 | var q = AutoQuery.CreateQuery(query, Request, 69 | db: new MemoryDataSource(logs, query, Request)); 70 | 71 | return AutoQuery.Execute(query, q); 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /src/ServiceStack.Admin.Web/App_Data/db.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ServiceStack/Admin/d6dda10b17761d109781d167b5da175d33126f53/src/ServiceStack.Admin.Web/App_Data/db.sqlite -------------------------------------------------------------------------------- /src/ServiceStack.Admin.Web/GitHubQuery.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using ServiceStack.DataAnnotations; 3 | 4 | namespace ServiceStack.Admin.Web 5 | { 6 | [Route("/repos")] 7 | [AutoQueryViewer(Name = "ServiceStack Repo's", 8 | Title = "ServiceStack Repositories", Description = "Browse different ServiceStack repos", 9 | DefaultSearchField = "Language", DefaultSearchType = "=", DefaultSearchText = "C#", 10 | IconUrl = "octicon:repo", 11 | DefaultFields = "Id,Name,Language,Description:500,Homepage,Has_Wiki")] 12 | public class QueryRepos : QueryDb { } 13 | 14 | [Route("/commits")] 15 | [AutoQueryViewer(Title = "ServiceStack Commits", Description = "Browse latest 1000 commits", 16 | DefaultSearchField = "Message", DefaultSearchType = "Contains", DefaultSearchText = "AutoQuery", 17 | //IconUrl = "octicon:history" 18 | IconUrl = "https://raw.githubusercontent.com/ServiceStackApps/GitHubAutoQuery/master/src/GitHubAutoQuery/GitHubAutoQuery/img/app/commits-75.png" 19 | )] 20 | public class QueryRepoCommits : QueryDb { } 21 | 22 | [Route("/contents")] 23 | [AutoQueryViewer(Title = "ServiceStack Files", Description = "Browse ServiceStack top-level files and folders", 24 | DefaultSearchField = "Type", DefaultSearchType = "=", DefaultSearchText = "file", 25 | IconUrl = "octicon:file-directory")] 26 | public class QueryRepoContent : QueryDb { } 27 | 28 | [Route("/contributors")] 29 | [AutoQueryViewer(Title = "ServiceStack Contributors", Description = "Browse ServiceStack Contributors", 30 | DefaultSearchField = "Contributions", DefaultSearchType = ">=", DefaultSearchText = "5", 31 | IconUrl = "octicon:organization")] 32 | public class QueryRepoContributors : QueryDb { } 33 | 34 | [Route("/subscribers")] 35 | [AutoQueryViewer(Title = "ServiceStack Subscribers", Description = "Browse ServiceStack Subscribers", 36 | DefaultSearchField = "Type", DefaultSearchType = "=", DefaultSearchText = "User", 37 | IconUrl = "octicon:eye")] 38 | public class QueryRepoSubscribers : QueryDb { } 39 | 40 | //[Route("/comments")] 41 | //[AutoQueryViewer(Title = "ServiceStack Comments", Description = "Browse ServiceStack Subscribers", 42 | // DefaultSearchField = "Id", DefaultSearchType = ">", DefaultSearchText = "0", 43 | // IconUrl = "octicon:comments")] 44 | public class QueryRepoComments : QueryDb { } 45 | 46 | [Route("/releases")] 47 | [AutoQueryViewer(Title = "ServiceStack Releases", Description = "Browse ServiceStack Releases", 48 | DefaultSearchField = "Name", DefaultSearchType = "Starts With", DefaultSearchText = "v4", 49 | IconUrl = "octicon:tag")] 50 | public class QueryRepoReleases : QueryDb { } 51 | 52 | public class GithubRepo 53 | { 54 | public int Id { get; set; } 55 | public string Name { get; set; } 56 | public string Description { get; set; } 57 | public string Homepage { get; set; } 58 | public string Language { get; set; } 59 | public int Watchers_Count { get; set; } 60 | public int Stargazes_Count { get; set; } 61 | public int Forks_Count { get; set; } 62 | public int Open_Issues_Count { get; set; } 63 | public int Size { get; set; } 64 | public string Full_Name { get; set; } 65 | public DateTime Created_at { get; set; } 66 | public DateTime? Pushed_At { get; set; } 67 | public DateTime? Updated_At { get; set; } 68 | 69 | public bool Has_issues { get; set; } 70 | public bool Has_Downloads { get; set; } 71 | public bool Has_Wiki { get; set; } 72 | public bool Has_Pages { get; set; } 73 | public bool Fork { get; set; } 74 | 75 | public GithubUser Owner { get; set; } 76 | public string Svn_Url { get; set; } 77 | public string Mirror_Url { get; set; } 78 | public string Url { get; set; } 79 | public string Ssh_Url { get; set; } 80 | public string Html_Url { get; set; } 81 | public string Clone_Url { get; set; } 82 | public string Git_Url { get; set; } 83 | public bool Private { get; set; } 84 | } 85 | 86 | public abstract class GithubUser 87 | { 88 | public int Id { get; set; } 89 | public string Login { get; set; } 90 | public string Avatar_Url { get; set; } 91 | public string Url { get; set; } 92 | public int? Followers { get; set; } 93 | public int? Following { get; set; } 94 | public string Type { get; set; } 95 | public int? Public_Gists { get; set; } 96 | public string Location { get; set; } 97 | public string Company { get; set; } 98 | public string Html_Url { get; set; } 99 | public int? Public_Repos { get; set; } 100 | public DateTime? Created_At { get; set; } 101 | public string Blog { get; set; } 102 | public string Email { get; set; } 103 | public string Name { get; set; } 104 | public bool? Hireable { get; set; } 105 | public string Gravatar_Id { get; set; } 106 | public string Bio { get; set; } 107 | } 108 | 109 | public class GithubOrg 110 | { 111 | public int Id { get; set; } 112 | public string Avatar_Url { get; set; } 113 | public string Url { get; set; } 114 | public string Login { get; set; } 115 | } 116 | 117 | public class GithubByUser 118 | { 119 | public string Name { get; set; } 120 | public string Email { get; set; } 121 | public DateTime Date { get; set; } 122 | } 123 | 124 | public class GithubCommitResult 125 | { 126 | public string Sha { get; set; } 127 | public GithubCommit Commit { get; set; } 128 | public GithubUser Author { get; set; } 129 | public GithubUser Committer { get; set; } 130 | } 131 | 132 | public class GithubCommit 133 | { 134 | public string Id { get; set; } 135 | public string Message { get; set; } 136 | public DateTime Date { get; set; } 137 | public string Name { get; set; } 138 | public int Comment_Count { get; set; } 139 | public GithubByUser Committer { get; set; } 140 | public GithubByUser Author { get; set; } 141 | 142 | public bool? ShouldSerialize(string fieldName) 143 | { 144 | return fieldName != "Committer" && fieldName != "Author"; 145 | } 146 | } 147 | 148 | public class GithubContent 149 | { 150 | [PrimaryKey] 151 | public string Sha { get; set; } 152 | public string Path { get; set; } 153 | public string Name { get; set; } 154 | public string Type { get; set; } 155 | public int Size { get; set; } 156 | public string Download_Url { get; set; } 157 | } 158 | 159 | public class GithubContributor 160 | { 161 | public int Id { get; set; } 162 | public string Login { get; set; } 163 | public int Contributions { get; set; } 164 | public string Type { get; set; } 165 | 166 | public string Avatar_Url { get; set; } 167 | public string Gravatar_Id { get; set; } 168 | public string Url { get; set; } 169 | public bool? Site_Admin { get; set; } 170 | } 171 | 172 | public class GithubSubscriber 173 | { 174 | public int Id { get; set; } 175 | public string Login { get; set; } 176 | public int Contributions { get; set; } 177 | public string Type { get; set; } 178 | 179 | public string Avatar_Url { get; set; } 180 | public string Gravatar_Id { get; set; } 181 | public string Url { get; set; } 182 | public bool? Site_Admin { get; set; } 183 | } 184 | 185 | public class GithubComment 186 | { 187 | public int Id { get; set; } 188 | public string Body { get; set; } 189 | public DateTime Created_At { get; set; } 190 | public DateTime Updated_At { get; set; } 191 | public GithubUser User { get; set; } 192 | public string Url { get; set; } 193 | public string Commit_Id { get; set; } 194 | 195 | public string Position { get; set; } 196 | public string Line { get; set; } 197 | public string Path { get; set; } 198 | } 199 | 200 | public class GithubRelease 201 | { 202 | public int Id { get; set; } 203 | public string Name { get; set; } 204 | public string Tag_Name { get; set; } 205 | public string Target_Commitish { get; set; } 206 | public string Body { get; set; } 207 | 208 | public bool Draft { get; set; } 209 | public bool PreRelease { get; set; } 210 | 211 | public DateTime Created_At { get; set; } 212 | public DateTime Published_At { get; set; } 213 | public GithubUser Author { get; set; } 214 | public string Url { get; set; } 215 | public string Tarball_Url { get; set; } 216 | public string Zipball_Url { get; set; } 217 | } 218 | 219 | } -------------------------------------------------------------------------------- /src/ServiceStack.Admin.Web/Global.asax: -------------------------------------------------------------------------------- 1 | <%@ Application Codebehind="Global.asax.cs" Inherits="ServiceStack.Admin.Web.Global" Language="C#" %> 2 | -------------------------------------------------------------------------------- /src/ServiceStack.Admin.Web/Global.asax.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Security; 6 | using System.Web.SessionState; 7 | 8 | namespace ServiceStack.Admin.Web 9 | { 10 | public class Global : System.Web.HttpApplication 11 | { 12 | protected void Application_Start(object sender, EventArgs e) 13 | { 14 | new AppHost().Init(); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/ServiceStack.Admin.Web/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ServiceStack.Admin.Web")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ServiceStack.Admin.Web")] 13 | [assembly: AssemblyCopyright("Copyright © 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("03fe49cf-d70f-4041-b4aa-c175fd4d0dfe")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Revision and Build Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("4.5.9.0")] 35 | [assembly: AssemblyFileVersion("4.5.9.0")] 36 | -------------------------------------------------------------------------------- /src/ServiceStack.Admin.Web/ServiceStack.Admin.Web.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Debug 7 | AnyCPU 8 | 9 | 10 | 2.0 11 | {F4DBDDEF-2F92-4EDF-96A8-A33F8F14C42B} 12 | {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} 13 | Library 14 | Properties 15 | ServiceStack.Admin.Web 16 | ServiceStack.Admin.Web 17 | v4.7.2 18 | true 19 | 20 | 21 | 22 | 23 | ..\..\ 24 | true 25 | 26 | 2.5 27 | true 28 | 29 | 30 | 31 | 32 | 33 | 34 | true 35 | full 36 | false 37 | bin\ 38 | DEBUG;TRACE 39 | prompt 40 | 4 41 | 42 | 43 | pdbonly 44 | true 45 | bin\ 46 | TRACE 47 | prompt 48 | 4 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | Global.asax 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | Web.config 80 | 81 | 82 | Web.config 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 10.0 137 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | True 149 | True 150 | 62428 151 | / 152 | http://localhost:62428/ 153 | False 154 | False 155 | 156 | 157 | False 158 | 159 | 160 | 161 | 162 | 169 | -------------------------------------------------------------------------------- /src/ServiceStack.Admin.Web/StackOverflowQuery.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using ServiceStack.DataAnnotations; 3 | using ServiceStack.OrmLite; 4 | 5 | namespace ServiceStack.Admin.Web 6 | { 7 | [Route("/questions")] 8 | [AutoQueryViewer( 9 | Title = "Explore StackOverflow Questions", Description = "Find ServiceStack Questions on StackOverflow", 10 | IconUrl = "material-icons:cast", DefaultSearchField = "Title", DefaultSearchType = "Contains", DefaultSearchText = "ServiceStack")] 11 | public class StackOverflowQuery : QueryDb 12 | { 13 | public int? ScoreGreaterThan { get; set; } 14 | } 15 | 16 | [Route("/questions/search")] 17 | public class SearchQuestions : IReturn 18 | { 19 | public List Tags { get; set; } 20 | public string UserId { get; set; } 21 | } 22 | 23 | [Description("Get a list of Answers for a Question")] 24 | [Route("/answers/{QuestionId}")] 25 | public class GetAnswers : IReturn 26 | { 27 | public int QuestionId { get; set; } 28 | } 29 | 30 | public class StackOverflowServices : Service 31 | { 32 | public object Get(SearchQuestions request) 33 | { 34 | var query = Db.From(); 35 | 36 | if (request.Tags != null && request.Tags.Count > 0) 37 | { 38 | query.Join((q, t) => q.QuestionId == t.QuestionId) 39 | .Where(x => Sql.In(x.Tag, request.Tags)); 40 | } 41 | 42 | var response = new SearchQuestionsResponse 43 | { 44 | Results = Db.Select(query) 45 | }; 46 | 47 | return response; 48 | } 49 | 50 | public object Get(GetAnswers request) 51 | { 52 | return new GetAnswersResponse 53 | { 54 | Ansnwer = Db.Single(x => x.QuestionId == request.QuestionId) 55 | }; 56 | } 57 | } 58 | 59 | public class SearchQuestionsResponse 60 | { 61 | public List Results { get; set; } 62 | } 63 | 64 | public class GetAnswersResponse 65 | { 66 | public Answer Ansnwer { get; set; } 67 | } 68 | 69 | public class AnswersResponse 70 | { 71 | public List Items { get; set; } 72 | public bool HasMore { get; set; } 73 | public int QuotaMax { get; set; } 74 | public int QuotaRemaining { get; set; } 75 | } 76 | 77 | public class QuestionsResponse 78 | { 79 | public List Items { get; set; } 80 | public bool HasMore { get; set; } 81 | public int QuotaMax { get; set; } 82 | public int QuotaRemaining { get; set; } 83 | } 84 | 85 | public class User 86 | { 87 | public int Reputation { get; set; } 88 | public int Userid { get; set; } 89 | public string UserType { get; set; } 90 | public int AcceptRate { get; set; } 91 | public string ProfileImage { get; set; } 92 | public string DisplayName { get; set; } 93 | public string Link { get; set; } 94 | } 95 | 96 | public class Question 97 | { 98 | [PrimaryKey] 99 | [Alias("Id")] 100 | public int QuestionId { get; set; } 101 | 102 | public string Title { get; set; } 103 | public int Score { get; set; } 104 | public int ViewCount { get; set; } 105 | public bool IsAnswered { get; set; } 106 | public int AnswerCount { get; set; } 107 | public string Link { get; set; } 108 | public string[] Tags { get; set; } 109 | public User Owner { get; set; } 110 | public int LastActivityDate { get; set; } 111 | public int CreationDate { get; set; } 112 | public int LastEditDate { get; set; } 113 | public int? AcceptedAnswerId { get; set; } 114 | } 115 | 116 | public class QuestionTag 117 | { 118 | [AutoIncrement] 119 | public int Id { get; set; } 120 | public int QuestionId { get; set; } 121 | public string Tag { get; set; } 122 | } 123 | 124 | public class Answer 125 | { 126 | [PrimaryKey] 127 | [Alias("Id")] 128 | public int AnswerId { get; set; } 129 | 130 | public User Owner { get; set; } 131 | public bool IsAccepted { get; set; } 132 | public int Score { get; set; } 133 | public int LastActivityDate { get; set; } 134 | public int LastEditDate { get; set; } 135 | public int CreationDate { get; set; } 136 | public int QuestionId { get; set; } 137 | } 138 | } -------------------------------------------------------------------------------- /src/ServiceStack.Admin.Web/Web.Debug.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 29 | 30 | -------------------------------------------------------------------------------- /src/ServiceStack.Admin.Web/Web.Release.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | 30 | 31 | -------------------------------------------------------------------------------- /src/ServiceStack.Admin.Web/Web.config: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | 9 | 10 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /src/ServiceStack.Admin.Web/dist/img/MaterialIcons-Regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ServiceStack/Admin/d6dda10b17761d109781d167b5da175d33126f53/src/ServiceStack.Admin.Web/dist/img/MaterialIcons-Regular.eot -------------------------------------------------------------------------------- /src/ServiceStack.Admin.Web/dist/img/MaterialIcons-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ServiceStack/Admin/d6dda10b17761d109781d167b5da175d33126f53/src/ServiceStack.Admin.Web/dist/img/MaterialIcons-Regular.ttf -------------------------------------------------------------------------------- /src/ServiceStack.Admin.Web/dist/img/MaterialIcons-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ServiceStack/Admin/d6dda10b17761d109781d167b5da175d33126f53/src/ServiceStack.Admin.Web/dist/img/MaterialIcons-Regular.woff -------------------------------------------------------------------------------- /src/ServiceStack.Admin.Web/dist/img/MaterialIcons-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ServiceStack/Admin/d6dda10b17761d109781d167b5da175d33126f53/src/ServiceStack.Admin.Web/dist/img/MaterialIcons-Regular.woff2 -------------------------------------------------------------------------------- /src/ServiceStack.Admin.Web/dist/img/octicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ServiceStack/Admin/d6dda10b17761d109781d167b5da175d33126f53/src/ServiceStack.Admin.Web/dist/img/octicons.ttf -------------------------------------------------------------------------------- /src/ServiceStack.Admin.Web/dist/img/octicons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ServiceStack/Admin/d6dda10b17761d109781d167b5da175d33126f53/src/ServiceStack.Admin.Web/dist/img/octicons.woff -------------------------------------------------------------------------------- /src/ServiceStack.Admin.Web/dist/img/roboto-v15-latin-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ServiceStack/Admin/d6dda10b17761d109781d167b5da175d33126f53/src/ServiceStack.Admin.Web/dist/img/roboto-v15-latin-regular.woff -------------------------------------------------------------------------------- /src/ServiceStack.Admin.Web/dist/img/roboto-v15-latin-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ServiceStack/Admin/d6dda10b17761d109781d167b5da175d33126f53/src/ServiceStack.Admin.Web/dist/img/roboto-v15-latin-regular.woff2 -------------------------------------------------------------------------------- /src/ServiceStack.Admin.Web/gulpfile.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var MSBUILD_TOOLS_VERSION = getMSBuildToolsVersion(); 3 | var SCRIPTS = { 4 | '00-webpack-dev': 'npm run dev', 5 | '00-webpack-watch': 'npm run watch', 6 | 'webpack-build': 'npm run build', 7 | 'webpack-build-prod': 'npm run build-prod', 8 | 'tests-run': 'npm run test', 9 | 'tests-watch': 'npm run test-watch', 10 | 'tests-coverage': 'npm run test-coverage', 11 | 'update-dtos': 'npm run typescript-ref' 12 | }; 13 | 14 | var fs = require('fs'); 15 | var path = require('path'); 16 | var gulp = require('gulp'); 17 | var gulpUtil = require('gulp-util'); 18 | var exec = require('child_process').exec; 19 | var runSequence = require('run-sequence'); 20 | var nugetRestore = require('gulp-nuget-restore'); 21 | var msbuild = require('gulp-msbuild'); 22 | var msdeploy = require('gulp-msdeploy'); 23 | 24 | var webRoot = 'wwwroot/'; 25 | var webBuildDir = './wwwroot_build/'; 26 | var configDir = webBuildDir + 'publish/'; 27 | var configPath = configDir + 'config.json'; 28 | var appSettingsDir = webBuildDir + 'deploy/'; 29 | var appSettingsPath = appSettingsDir + 'appsettings.txt'; 30 | 31 | function createConfigsIfMissing() { 32 | if (!fs.existsSync(configPath)) { 33 | if (!fs.existsSync(configDir)) { 34 | fs.mkdirSync(configDir); 35 | } 36 | fs.writeFileSync(configPath, JSON.stringify({ 37 | "iisApp": "ServiceStack.Admin.Web", 38 | "serverAddress": "deploy-server.example.com", 39 | "userName": "{WebDeployUserName}", 40 | "password": "{WebDeployPassword}" 41 | }, null, 4)); 42 | } 43 | if (!fs.existsSync(appSettingsPath)) { 44 | if (!fs.existsSync(appSettingsDir)) { 45 | fs.mkdirSync(appSettingsDir); 46 | } 47 | fs.writeFileSync(appSettingsPath, 48 | '# Release App Settings\r\nDebugMode false'); 49 | } 50 | } 51 | 52 | createConfigsIfMissing(); 53 | 54 | function getMSBuildToolsVersion() { 55 | fs = fs || require("fs"); 56 | return fs.existsSync(process.env["PROGRAMFILES(X86)"] + "/MSBuild/15.0") ? 57 | 15 58 | : fs.existsSync(process.env["PROGRAMFILES(X86)"] + "/MSBuild/14.0") ? 59 | 14 : 60 | null; 61 | } 62 | 63 | function runScript(script, done) { 64 | process.env.FORCE_COLOR = 1; 65 | var proc = exec(script + (script.startsWith("npm") ? " --silent" : "")); 66 | proc.stdout.pipe(process.stdout); 67 | proc.stderr.pipe(process.stderr); 68 | proc.on('exit', () => done()); 69 | } 70 | 71 | // Tasks 72 | Object.keys(SCRIPTS).forEach(name => { 73 | gulp.task(name, done => runScript(SCRIPTS[name], done)); 74 | }); 75 | gulp.task('www-postinstall', done => { 76 | runSequence( 77 | 'webpack-build', 78 | done); 79 | }); 80 | gulp.task('www-msbuild', () => { 81 | return gulp.src('../../ServiceStack.Admin.Web.sln') 82 | .pipe(nugetRestore()) 83 | .pipe(msbuild({ 84 | toolsVersion: MSBUILD_TOOLS_VERSION, 85 | targets: ['Clean', 'Build'], 86 | properties: { 87 | Configuration: 'Release' 88 | }, 89 | stdout: true, 90 | verbosity: 'quiet' 91 | })); 92 | }); 93 | gulp.task('www-msdeploy-pack', () => { 94 | return gulp.src('wwwroot/') 95 | .pipe(msdeploy({ 96 | verb: 'sync', 97 | sourceType: 'iisApp', 98 | dest: { 99 | 'package': path.resolve('./webdeploy.zip') 100 | } 101 | })); 102 | }); 103 | gulp.task('www-msdeploy-push', () => { 104 | var config = require(configPath); 105 | return gulp.src('./webdeploy.zip') 106 | .pipe(msdeploy({ 107 | verb: 'sync', 108 | allowUntrusted: 'true', 109 | sourceType: 'package', 110 | dest: { 111 | iisApp: config.iisApp, 112 | wmsvc: config.serverAddress, 113 | UserName: config.userName, 114 | Password: config.password 115 | } 116 | })); 117 | }); 118 | 119 | gulp.task('01-package-server', done => { 120 | runSequence('www-msbuild', done); 121 | }); 122 | 123 | gulp.task('02-package-client', done => { 124 | runSequence('webpack-build-prod', done); 125 | }); 126 | 127 | gulp.task('03-deploy-app', done => { 128 | runSequence('www-msdeploy-pack', 'www-msdeploy-push', done); 129 | }); 130 | 131 | gulp.task('package-and-deploy', done => { 132 | runSequence('01-package-server', '02-package-client', '03-deploy-app', done); 133 | }); 134 | 135 | })(); -------------------------------------------------------------------------------- /src/ServiceStack.Admin.Web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | AutoQuery 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/ServiceStack.Admin.Web/index.template.ejs: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | AutoQuery 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/ServiceStack.Admin.Web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "service-stack.-admin.-web", 3 | "version": "0.0.1", 4 | "scripts": { 5 | "postinstall": "gulp www-postinstall", 6 | "dev": "webpack-dev-server", 7 | "watch": "webpack --config webpack.config.js --watch", 8 | "build": "webpack --config webpack.config.js", 9 | "build-prod": "webpack --config webpack.config.js", 10 | "test": "jest", 11 | "test-watch": "jest --watch", 12 | "test-coverage": "jest --coverage", 13 | "typescript-ref": "cd src && typescript-ref" 14 | }, 15 | "jest": { 16 | "globals": { 17 | "BaseUrl": "http://localhost:62428/" 18 | }, 19 | "transform": { 20 | ".(ts|tsx)": "/node_modules/ts-jest/preprocessor.js" 21 | }, 22 | "testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$", 23 | "moduleFileExtensions": [ 24 | "ts", 25 | "tsx", 26 | "js" 27 | ], 28 | "moduleNameMapper": { 29 | "^.+\\.(css|scss|sass)$": "identity-obj-proxy", 30 | "^.+\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "/src/test.fileMock.js" 31 | } 32 | }, 33 | "dependencies": { 34 | "bootstrap": "^4.0.0-alpha.6", 35 | "classnames": "^2.2.5", 36 | "es6-shim": "^0.35.3", 37 | "font-awesome": "^4.7.0", 38 | "react": "^15.2.1", 39 | "react-dom": "^15.5.4", 40 | "react-router": "^4.1.1", 41 | "react-router-dom": "^4.1.1", 42 | "servicestack-client": "0.0.35" 43 | }, 44 | "devDependencies": { 45 | "@types/classnames": "2.2.0", 46 | "@types/jest": "^19.2.3", 47 | "@types/node": "^7.0.18", 48 | "@types/react": "^15.0.33", 49 | "@types/react-dom": "^15.5.1", 50 | "@types/react-router": "^4.0.12", 51 | "autoprefixer": "^7.1.0", 52 | "awesome-typescript-loader": "^3.1.3", 53 | "chalk": "^1.1.3", 54 | "clean-webpack-plugin": "^0.1.16", 55 | "copy-webpack-plugin": "^4.0.1", 56 | "css-loader": "^0.28.1", 57 | "enzyme": "^2.8.2", 58 | "extract-text-webpack-plugin": "^2.1.0", 59 | "file-loader": "^0.11.1", 60 | "gulp": "~3.9.1", 61 | "gulp-msbuild": "^0.4.7", 62 | "gulp-msdeploy": "^0.0.4", 63 | "gulp-nuget-pack": "^0.0.7", 64 | "gulp-nuget-restore": "^0.5.0", 65 | "gulp-util": "^3.0.7", 66 | "html-loader": "0.4.5", 67 | "html-webpack-plugin": "^2.28.0", 68 | "identity-obj-proxy": "^3.0.0", 69 | "image-webpack-loader": "^3.3.1", 70 | "jest": "^20.0.1", 71 | "node-sass": "^4.5.3", 72 | "postcss-loader": "^2.0.5", 73 | "precss": "^1.4.0", 74 | "react-test-renderer": "^15.5.4", 75 | "run-sequence": "^1.2.2", 76 | "sass-loader": "^6.0.5", 77 | "servicestack-cli": "0.0.5", 78 | "source-map-loader": "^0.2.1", 79 | "style-loader": "^0.17.0", 80 | "ts-jest": "^20.0.3", 81 | "typescript": "^2.4.1", 82 | "url-loader": "^0.5.8", 83 | "webpack": "^2.5.1", 84 | "webpack-dev-server": "^2.4.5" 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/ServiceStack.Admin.Web/requestlogs/2016-04/2016-04-11-errors.csv: -------------------------------------------------------------------------------- 1 | Id,DateTime,HttpMethod,AbsoluteUri,PathInfo,RequestBody,RequestDto,UserAuthId,SessionId,IpAddress,ForwardedFor,Referer,Headers,FormData,Items,Session,ResponseDto,ErrorResponse,RequestDuration 2 | 21,2016-04-13T21:21:28.6402944Z,GET,http://localhost:55799/json/reply/CustomHttpError,/json/reply/CustomHttpError,,{StatusCode:0},3,b4ctpvV7zFHtSMBWOwya,::1,,,"{Connection:keep-alive,Accept:""text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"",Accept-Encoding:""gzip, deflate, sdch"",Accept-Language:""en-US,en;q=0.8"",Cookie:_ga=GA1.1.1592632894.1443244591; __utma=111872281.1592632894.1443244591.1457727021.1459534479.12; __utmc=111872281; __utmz=111872281.1454897587.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); ss-id=b4ctpvV7zFHtSMBWOwya; ss-pid=igyyWJIl7IUZkzZHExbt; X-UAId=3,Host:""localhost:55799"",User-Agent:""Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36"",Upgrade-Insecure-Requests:1}",{},"{AspSessionIDManagerInitializeRequestCalled:True,"":mini-profiler:"":""http://localhost:55799/json/reply/CustomHttpError (28.9 ms)"",_requestDurationStopwatch:System.Diagnostics.Stopwatch}",,,"{ResponseStatus:{ErrorCode:0,Message:0,StackTrace:""[CustomHttpError: 4/13/2016 9:21:28 PM]: 3 | [REQUEST: {StatusCode:0}] 4 | ServiceStack.HttpError: 0 5 | at Check.ServiceInterface.CustomHttpErrorService.Any(CustomHttpError request) in C:\src\ServiceStack\tests\Check.ServiceInterface\ErrorServices.cs:line 11 6 | at lambda_method(Closure , Object , Object ) 7 | at ServiceStack.Host.ServiceRunner`1.Execute(IRequest request, Object instance, TRequest requestDto) in C:\src\ServiceStack\src\ServiceStack\Host\ServiceRunner.cs:line 104"",Errors:[]}}",PT0.0228031S 8 | 24,2016-04-13T21:21:42.8043166Z,GET,http://localhost:55799/json/reply/CustomHttpError?StatusCode=401,/json/reply/CustomHttpError,,{StatusCode:401},3,b4ctpvV7zFHtSMBWOwya,::1,,,"{Connection:keep-alive,Accept:""text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"",Accept-Encoding:""gzip, deflate, sdch"",Accept-Language:""en-US,en;q=0.8"",Cookie:_ga=GA1.1.1592632894.1443244591; __utma=111872281.1592632894.1443244591.1457727021.1459534479.12; __utmc=111872281; __utmz=111872281.1454897587.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); ss-id=b4ctpvV7zFHtSMBWOwya; ss-pid=igyyWJIl7IUZkzZHExbt; X-UAId=3,Host:""localhost:55799"",User-Agent:""Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36"",Upgrade-Insecure-Requests:1}",{},"{AspSessionIDManagerInitializeRequestCalled:True,"":mini-profiler:"":""http://localhost:55799/json/reply/CustomHttpError?StatusCode=401 (1.5 ms)"",_requestDurationStopwatch:System.Diagnostics.Stopwatch}",,,"{ResponseStatus:{ErrorCode:401,Message:401,StackTrace:""[CustomHttpError: 4/13/2016 9:21:42 PM]: 9 | [REQUEST: {StatusCode:401}] 10 | ServiceStack.HttpError: 401 11 | at Check.ServiceInterface.CustomHttpErrorService.Any(CustomHttpError request) in C:\src\ServiceStack\tests\Check.ServiceInterface\ErrorServices.cs:line 11 12 | at lambda_method(Closure , Object , Object ) 13 | at ServiceStack.Host.ServiceRunner`1.Execute(IRequest request, Object instance, TRequest requestDto) in C:\src\ServiceStack\src\ServiceStack\Host\ServiceRunner.cs:line 104"",Errors:[]}}",PT0.0002784S 14 | -------------------------------------------------------------------------------- /src/ServiceStack.Admin.Web/requestlogs/2016-04/2016-04-12-errors.csv: -------------------------------------------------------------------------------- 1 | Id,DateTime,HttpMethod,AbsoluteUri,PathInfo,RequestBody,RequestDto,UserAuthId,SessionId,IpAddress,ForwardedFor,Referer,Headers,FormData,Items,Session,ResponseDto,ErrorResponse,RequestDuration 2 | 21,2016-04-13T21:21:28.6402944Z,GET,http://localhost:55799/json/reply/CustomHttpError,/json/reply/CustomHttpError,,{StatusCode:0},3,b4ctpvV7zFHtSMBWOwya,::1,,,"{Connection:keep-alive,Accept:""text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"",Accept-Encoding:""gzip, deflate, sdch"",Accept-Language:""en-US,en;q=0.8"",Cookie:_ga=GA1.1.1592632894.1443244591; __utma=111872281.1592632894.1443244591.1457727021.1459534479.12; __utmc=111872281; __utmz=111872281.1454897587.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); ss-id=b4ctpvV7zFHtSMBWOwya; ss-pid=igyyWJIl7IUZkzZHExbt; X-UAId=3,Host:""localhost:55799"",User-Agent:""Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36"",Upgrade-Insecure-Requests:1}",{},"{AspSessionIDManagerInitializeRequestCalled:True,"":mini-profiler:"":""http://localhost:55799/json/reply/CustomHttpError (28.9 ms)"",_requestDurationStopwatch:System.Diagnostics.Stopwatch}",,,"{ResponseStatus:{ErrorCode:0,Message:0,StackTrace:""[CustomHttpError: 4/13/2016 9:21:28 PM]: 3 | [REQUEST: {StatusCode:0}] 4 | ServiceStack.HttpError: 0 5 | at Check.ServiceInterface.CustomHttpErrorService.Any(CustomHttpError request) in C:\src\ServiceStack\tests\Check.ServiceInterface\ErrorServices.cs:line 11 6 | at lambda_method(Closure , Object , Object ) 7 | at ServiceStack.Host.ServiceRunner`1.Execute(IRequest request, Object instance, TRequest requestDto) in C:\src\ServiceStack\src\ServiceStack\Host\ServiceRunner.cs:line 104"",Errors:[]}}",PT0.0228031S 8 | 24,2016-04-13T21:21:42.8043166Z,GET,http://localhost:55799/json/reply/CustomHttpError?StatusCode=401,/json/reply/CustomHttpError,,{StatusCode:401},3,b4ctpvV7zFHtSMBWOwya,::1,,,"{Connection:keep-alive,Accept:""text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"",Accept-Encoding:""gzip, deflate, sdch"",Accept-Language:""en-US,en;q=0.8"",Cookie:_ga=GA1.1.1592632894.1443244591; __utma=111872281.1592632894.1443244591.1457727021.1459534479.12; __utmc=111872281; __utmz=111872281.1454897587.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); ss-id=b4ctpvV7zFHtSMBWOwya; ss-pid=igyyWJIl7IUZkzZHExbt; X-UAId=3,Host:""localhost:55799"",User-Agent:""Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36"",Upgrade-Insecure-Requests:1}",{},"{AspSessionIDManagerInitializeRequestCalled:True,"":mini-profiler:"":""http://localhost:55799/json/reply/CustomHttpError?StatusCode=401 (1.5 ms)"",_requestDurationStopwatch:System.Diagnostics.Stopwatch}",,,"{ResponseStatus:{ErrorCode:401,Message:401,StackTrace:""[CustomHttpError: 4/13/2016 9:21:42 PM]: 9 | [REQUEST: {StatusCode:401}] 10 | ServiceStack.HttpError: 401 11 | at Check.ServiceInterface.CustomHttpErrorService.Any(CustomHttpError request) in C:\src\ServiceStack\tests\Check.ServiceInterface\ErrorServices.cs:line 11 12 | at lambda_method(Closure , Object , Object ) 13 | at ServiceStack.Host.ServiceRunner`1.Execute(IRequest request, Object instance, TRequest requestDto) in C:\src\ServiceStack\src\ServiceStack\Host\ServiceRunner.cs:line 104"",Errors:[]}}",PT0.0002784S 14 | -------------------------------------------------------------------------------- /src/ServiceStack.Admin.Web/src/AutoQuery.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { render } from 'react-dom'; 3 | import Header from './Header'; 4 | import Sidebar from './Sidebar'; 5 | import Content from './Content'; 6 | import ColumnPrefsDialog from './ColumnPrefsDialog'; 7 | 8 | import { client, normalize } from './shared'; 9 | 10 | export default class AutoQuery extends React.Component { 11 | constructor(props?, context?) { 12 | super(props, context); 13 | this.state = { metadata: null }; 14 | 15 | client.get("/autoquery/metadata").then(r => { 16 | const metadata = normalize(r, true); 17 | this.setState({ metadata, name: this.getName() }) 18 | }); 19 | } 20 | 21 | render() { 22 | return this.state.metadata 23 | ? 24 | : null; 25 | } 26 | 27 | getName() { 28 | return this.props.match.params.name || ""; 29 | } 30 | } 31 | 32 | class App extends React.Component { 33 | constructor(props?, context?) { 34 | super(props, context); 35 | 36 | const operationNames = this.props.metadata.operations.map(op => op.request); 37 | 38 | const viewerArgs = {}, operations = {}, types = {}; 39 | operationNames.forEach(name => { 40 | viewerArgs[name] = {}; 41 | const aqViewer = this.getAutoQueryViewer(name); 42 | if (aqViewer && aqViewer.args) { 43 | aqViewer.args.forEach(arg => viewerArgs[name][arg.name] = arg.value); 44 | } 45 | 46 | operations[name] = this.props.metadata.operations.filter(op => op.request === name)[0]; 47 | }); 48 | 49 | console.log(this.props.metadata); 50 | this.props.metadata.types.forEach(t => types[t.name] = t); 51 | 52 | let operationState = {}; 53 | let json = localStorage.getItem("v1/operationState"); 54 | if (json) 55 | operationState = JSON.parse(json); 56 | 57 | this.state = { 58 | sidebarHidden: false, selected: null, 59 | operationState, operationNames, viewerArgs, operations, types 60 | }; 61 | } 62 | 63 | resolveProperties(type) { 64 | var props = (type.properties || []).slice(0); 65 | 66 | let inherits = type.inherits; 67 | while (inherits) { 68 | const t = this.state.types[inherits.name]; 69 | if (!t || !t.properties) continue; 70 | t.properties.forEach(p => props.push(p)); 71 | inherits = t.inherits; 72 | } 73 | 74 | return props; 75 | } 76 | 77 | toggleSidebar() { 78 | this.setState({ sidebarHidden: !this.state.sidebarHidden }); 79 | } 80 | 81 | getType(name: string) { 82 | return this.props.metadata.types.filter(op => op.name === name)[0]; 83 | } 84 | 85 | getAutoQueryViewer(name:string) { 86 | const type = this.getType(name); 87 | return type != null && type.attributes != null 88 | ? type.attributes.filter(attr => attr.name === "AutoQueryViewer")[0] 89 | : null; 90 | } 91 | 92 | getAutoQueryViewerArgValue(name:string, argName:string) { 93 | const aqViewer = this.getAutoQueryViewer(name); 94 | const arg = aqViewer 95 | ? aqViewer.args.filter(x => x.name === argName)[0] 96 | : null; 97 | return arg != null 98 | ? arg.value 99 | : null; 100 | } 101 | 102 | getTitle(selected) { 103 | return selected 104 | ? this.getAutoQueryViewerArgValue(selected.name, 'Title') || selected.name 105 | : null; 106 | } 107 | 108 | getOperationValues(name: string) { 109 | const viewerArgs = this.state.viewerArgs[name] || {}; 110 | return Object.assign({ 111 | searchField: viewerArgs["DefaultSearchField"] || "", 112 | searchType: viewerArgs["DefaultSearchType"] || "", 113 | searchText: viewerArgs["DefaultSearchText"], 114 | conditions: [], 115 | queries: [] 116 | }, this.state.operationState[name] || {}); 117 | } 118 | 119 | getSelected(name: string) { 120 | const operation = this.state.operations[name]; 121 | if (operation == null) 122 | return null; 123 | const requestType = this.state.types[name]; 124 | const fromType = this.state.types[operation.from]; 125 | const toType = this.state.types[operation.to]; 126 | return { 127 | name, operation, requestType, 128 | fromType, fromTypeFields: this.resolveProperties(toType), 129 | toType, toTypeFields: this.resolveProperties(toType) 130 | }; 131 | } 132 | 133 | onOperationChange(opName: string, newValues: any) { 134 | const op = this.getOperationValues(opName); 135 | 136 | Object.keys(newValues).forEach(k => { 137 | if (newValues[k] != null) 138 | op[k] = newValues[k]; 139 | }); 140 | 141 | this.setOperationValues(opName, op); 142 | } 143 | 144 | addCondition(opName:string) { 145 | const op = this.getOperationValues(opName); 146 | const condition = { 147 | id: `${op.searchField}|${op.searchType}|${op.searchText}`, 148 | searchField: op.searchField, 149 | searchType: op.searchType, 150 | searchText: op.searchText 151 | }; 152 | 153 | if (op.conditions.some(x => x.id === condition.id)) 154 | return; 155 | 156 | op.searchText = ""; 157 | op.conditions.push(condition); 158 | 159 | this.setOperationValues(opName, op); 160 | } 161 | 162 | removeCondition(opName: string, condition:any) { 163 | const op = this.getOperationValues(opName); 164 | op.conditions = op.conditions.filter(x => x.id !== condition.id); 165 | this.setOperationValues(opName, op); 166 | } 167 | 168 | setOperationValues(opName, op) { 169 | const operationState = Object.assign({}, this.state.operationState); 170 | operationState[opName] = op; 171 | this.setState({ operationState }); 172 | localStorage.setItem("v1/operationState", JSON.stringify(operationState)); 173 | } 174 | 175 | showDialog(dialog) { 176 | this.setState({ dialog }); 177 | setTimeout(() => document.getElementById(dialog).classList.toggle('active'), 0); 178 | } 179 | 180 | hideDialog() { 181 | this.setState({ dialog: null }); 182 | } 183 | 184 | saveQuery(opName:string) { 185 | const name = prompt("Save Query as:", "My Query"); 186 | if (!name) return; 187 | 188 | const op = this.getOperationValues(opName); 189 | if (!op.queries) { 190 | op.queries = []; 191 | } 192 | 193 | op.queries.push({ 194 | name, 195 | searchField: op.searchField, 196 | searchType: op.searchType, 197 | searchText: op.searchText, 198 | conditions: op.conditions.map(x => Object.assign({}, x)) 199 | }); 200 | 201 | this.setOperationValues(opName, op); 202 | } 203 | 204 | removeQuery(opName: string, query: any) { 205 | const op = this.getOperationValues(opName); 206 | if (!op.queries) return; 207 | op.queries = op.queries.filter(x => x.name != query.name); 208 | this.setOperationValues(opName, op); 209 | } 210 | 211 | loadQuery(opName: string, query: any) { 212 | const op = this.getOperationValues(opName); 213 | op.searchField = query.searchField; 214 | op.searchType = query.searchType; 215 | op.searchText = query.searchText; 216 | op.conditions = query.conditions; 217 | this.setOperationValues(opName, op); 218 | } 219 | 220 | render() { 221 | const selected = this.getSelected(this.props.name); 222 | const opName = selected && selected.name; 223 | return ( 224 |
225 |
this.toggleSidebar() } /> 226 |
227 |
228 | 233 | this.onOperationChange(opName, args)} 241 | onAddCondition={e => this.addCondition(opName)} 242 | onRemoveCondition={c => this.removeCondition(opName, c) } 243 | onShowDialog={id => this.showDialog(id) } 244 | onSaveQuery={() => this.saveQuery(opName) } 245 | onRemoveQuery={x => this.removeQuery(opName, x) } 246 | onLoadQuery={x => this.loadQuery(opName, x) } 247 | /> 248 |
249 |
250 | 251 | {this.state.dialog !== "column-prefs-dialog" ? null : ( 252 | this.hideDialog() } 253 | fields={selected.toTypeFields} 254 | values={this.getOperationValues(this.props.name)} 255 | onChange={args => this.onOperationChange(opName, args) } 256 | /> 257 | )} 258 |
259 | ); 260 | } 261 | } 262 | -------------------------------------------------------------------------------- /src/ServiceStack.Admin.Web/src/ColumnPrefsDialog.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { render } from 'react-dom'; 3 | 4 | export default class ColumnPrefsDialog extends React.Component { 5 | constructor(props?, context?) { 6 | super(props, context); 7 | this.state = {}; 8 | } 9 | 10 | resetFields() { 11 | var fields = []; 12 | this.props.onChange({ fields }); 13 | } 14 | 15 | selectField(field) { 16 | let fields = (this.props.values.fields || []); 17 | 18 | if (fields.indexOf(field) >= 0) 19 | fields = fields.filter(x => x !== field); 20 | else 21 | fields.push(field); 22 | 23 | this.props.onChange({ fields }); 24 | } 25 | 26 | render() { 27 | var fields = (this.props.values.fields || []); 28 | 29 | var CheckboxStyle = { 30 | verticalAlign: 'text-bottom', fontSize: '20px', margin: '0 5px 0 0' 31 | }; 32 | 33 | return ( 34 |
35 |
this.props.onClose()}> 36 |
e.stopPropagation() }> 37 | 38 |
39 |

Column Preferences

40 |
41 | 42 |
43 |
this.resetFields()} style={{ 44 | borderBottom: '1px solid #ccc', padding: '0 0 10px 0', margin: '0 0 15px 0', cursor: 'pointer' 45 | }}> 46 | 47 | {fields.length === 0 ? 'radio_button_checked' : 'radio_button_unchecked'} 48 | 49 | Show all columns 50 |
51 | 52 | {this.props.fields.map(f => ( 53 |
this.selectField(f.name)} style={{ margin: '0 0 5px 0', cursor: 'pointer' }}> 54 | 55 | {fields.indexOf(f.name) >= 0 ? 'check_box' : 'check_box_outline_blank'} 56 | 57 | {f.name} 58 |
59 | ))} 60 |
61 | 62 |
63 |
this.props.onClose()}> 64 | DONE 65 |
66 |
67 |
68 |
69 |
70 | ); 71 | } 72 | } -------------------------------------------------------------------------------- /src/ServiceStack.Admin.Web/src/Header.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | export default class Header extends React.Component { 4 | render() { 5 | return ( 6 |