Add support for hosting Elsa Dashboard on sub paths

This commit is contained in:
Sipke Schoorstra 2021-07-18 22:32:23 +02:00
parent 96fe0d4db3
commit 86d7fb318f
26 changed files with 440 additions and 53 deletions

View file

@ -327,6 +327,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "aspnetcore", "aspnetcore",
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Samples.CustomTenantIdSource", "src\samples\aspnet\Elsa.Samples.CustomTenantIdSource\Elsa.Samples.CustomTenantIdSource.csproj", "{6E191628-927B-42FB-8805-D2977D8FC4E3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ElsaDashboard.Samples.AspNetCore.SubPath", "src\samples\dashboard\aspnetcore\ElsaDashboard.Samples.AspNetCore.SubPath\ElsaDashboard.Samples.AspNetCore.SubPath.csproj", "{BB715C0C-BE88-4F7F-A43F-1F8DFC9A1388}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -757,6 +759,10 @@ Global
{6E191628-927B-42FB-8805-D2977D8FC4E3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6E191628-927B-42FB-8805-D2977D8FC4E3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6E191628-927B-42FB-8805-D2977D8FC4E3}.Release|Any CPU.Build.0 = Release|Any CPU
{BB715C0C-BE88-4F7F-A43F-1F8DFC9A1388}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BB715C0C-BE88-4F7F-A43F-1F8DFC9A1388}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BB715C0C-BE88-4F7F-A43F-1F8DFC9A1388}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BB715C0C-BE88-4F7F-A43F-1F8DFC9A1388}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -900,6 +906,7 @@ Global
{4D4022DD-244B-47EE-95FA-7071EC687B24} = {B43B546E-23F3-46E8-ACB7-D04F05CDA180}
{39DE1EE2-DF4F-44EB-9F5A-551BEADD6673} = {4673732F-2853-47BD-91B8-C95C229D2C89}
{6E191628-927B-42FB-8805-D2977D8FC4E3} = {22E75696-6FE9-436A-9097-EE21C603F818}
{BB715C0C-BE88-4F7F-A43F-1F8DFC9A1388} = {39DE1EE2-DF4F-44EB-9F5A-551BEADD6673}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {8B0975FD-7050-48B0-88C5-48C33378E158}

View file

@ -1,5 +1,5 @@
<elsa-studio-root server-url="@ServerUrl" monaco-lib-path="@MonacoLibPath">
<elsa-studio-dashboard></elsa-studio-dashboard>
<elsa-studio-dashboard base-path="@BasePath"></elsa-studio-dashboard>
</elsa-studio-root>
@code{
@ -9,5 +9,8 @@
[Parameter]
public string MonacoLibPath { get; set; } = "_content/Elsa.Designer.Components.Web/monaco-editor/min";
[Parameter]
public string BasePath { get; set; } = default!;
}

View file

@ -1,6 +1,6 @@
{
"name": "@elsa-workflows/elsa-workflows-studio",
"version": "2.1.9",
"version": "2.1.10",
"description": "Elsa Workflow Studio is a collection of web components to manage Elsa workflows stored on an Elsa Workflows server.",
"repository": {
"type": "git",

View file

@ -159,6 +159,7 @@ export namespace Components {
"propertyModel": ActivityDefinitionProperty;
}
interface ElsaStudioDashboard {
"basePath": string;
"culture": string;
"monacoLibPath": string;
"serverUrl": string;
@ -780,6 +781,7 @@ declare namespace LocalJSX {
"propertyModel"?: ActivityDefinitionProperty;
}
interface ElsaStudioDashboard {
"basePath"?: string;
"culture"?: string;
"monacoLibPath"?: string;
"serverUrl"?: string;

View file

@ -14,6 +14,7 @@ export class ElsaStudioDashboard {
@Prop({attribute: 'server-url', reflect: true}) serverUrl: string;
@Prop({attribute: 'monaco-lib-path', reflect: true}) monacoLibPath: string;
@Prop({attribute: 'culture', reflect: true}) culture: string;
@Prop({attribute: 'base-path', reflect: true}) basePath: string = '';
private i18next: i18n;
async componentWillLoad() {
@ -26,12 +27,7 @@ export class ElsaStudioDashboard {
const culture = this.culture;
const monacoLibPath = this.monacoLibPath;
const logoPath = getAssetPath('./assets/logo.png');
// TODO: Tunneling doesn't appear to be working in combination with the router.
// const tunnelState: DashboardState = {
// serverUrl: serverUrl,
// };
const basePath = this.basePath || '';
const IntlMessage = GetIntlMessage(this.i18next);
return (
@ -41,25 +37,25 @@ export class ElsaStudioDashboard {
<div class="elsa-flex elsa-items-center elsa-justify-between elsa-h-16">
<div class="elsa-flex elsa-items-center">
<div class="elsa-flex-shrink-0">
<stencil-route-link url="/"><img class="elsa-h-8 elsa-w-8" src={logoPath} alt="Workflow"/></stencil-route-link>
<stencil-route-link url={`${basePath}/`}><img class="elsa-h-8 elsa-w-8" src={logoPath} alt="Workflow"/></stencil-route-link>
</div>
<div class="hidden md:elsa-block">
<div class="elsa-ml-10 elsa-flex elsa-items-baseline elsa-space-x-4">
<stencil-route-link url="/workflow-definitions" anchorClass="elsa-text-gray-300 hover:elsa-bg-gray-700 hover:elsa-text-white elsa-px-3 elsa-py-2 elsa-rounded-md elsa-text-sm elsa-font-medium"
<stencil-route-link url={`${basePath}/workflow-definitions`} anchorClass="elsa-text-gray-300 hover:elsa-bg-gray-700 hover:elsa-text-white elsa-px-3 elsa-py-2 elsa-rounded-md elsa-text-sm elsa-font-medium"
activeClass="elsa-text-white elsa-bg-gray-900">
<IntlMessage label="WorkflowDefinitions"/>
</stencil-route-link>
<stencil-route-link url="/workflow-instances" anchorClass="elsa-text-gray-300 hover:elsa-bg-gray-700 hover:elsa-text-white elsa-px-3 elsa-py-2 elsa-rounded-md elsa-text-sm elsa-font-medium"
<stencil-route-link url={`${basePath}/workflow-instances`} anchorClass="elsa-text-gray-300 hover:elsa-bg-gray-700 hover:elsa-text-white elsa-px-3 elsa-py-2 elsa-rounded-md elsa-text-sm elsa-font-medium"
activeClass="elsa-text-white elsa-bg-gray-900">
<IntlMessage label="WorkflowInstances"/>
</stencil-route-link>
<stencil-route-link url="/workflow-registry" anchorClass="elsa-text-gray-300 hover:elsa-bg-gray-700 hover:elsa-text-white elsa-px-3 elsa-py-2 elsa-rounded-md elsa-text-sm elsa-font-medium"
<stencil-route-link url={`${basePath}/workflow-registry`} anchorClass="elsa-text-gray-300 hover:elsa-bg-gray-700 hover:elsa-text-white elsa-px-3 elsa-py-2 elsa-rounded-md elsa-text-sm elsa-font-medium"
activeClass="elsa-text-white elsa-bg-gray-900">
<IntlMessage label="WorkflowRegistry"/>
</stencil-route-link>
{/*<stencil-route-link url="/custom-activities" class="elsa-text-gray-300 hover:elsa-bg-gray-700 hover:elsa-text-white elsa-px-3 elsa-py-2 elsa-rounded-md elsa-text-sm elsa-font-medium">Custom Activities</stencil-route-link>*/}
<stencil-route-link url="/webhook-definitions" anchorClass="elsa-text-gray-300 hover:elsa-bg-gray-700 hover:elsa-text-white elsa-px-3 elsa-py-2 elsa-rounded-md elsa-text-sm elsa-font-medium"
<stencil-route-link url={`${basePath}/webhook-definitions`} anchorClass="elsa-text-gray-300 hover:elsa-bg-gray-700 hover:elsa-text-white elsa-px-3 elsa-py-2 elsa-rounded-md elsa-text-sm elsa-font-medium"
activeClass="elsa-text-white elsa-bg-gray-900">
<IntlMessage label="WebhookDefinitions"/>
</stencil-route-link>
@ -71,23 +67,20 @@ export class ElsaStudioDashboard {
</nav>
<main>
{/*<Tunnel.Provider state={tunnelState}>*/}
<stencil-router>
<stencil-route-switch scrollTopOffset={0}>
<stencil-route url="/" component="elsa-studio-home" exact={true} componentProps={{culture: culture}}/>
<stencil-route url="/workflow-registry" component="elsa-studio-workflow-registry" componentProps={{'serverUrl': serverUrl, culture: culture}} exact={true}/>
<stencil-route url="/workflow-registry/:id" component="elsa-studio-workflow-blueprint-view" componentProps={{'serverUrl': serverUrl, culture: culture}}/>
<stencil-route url="/workflow-definitions" component="elsa-studio-workflow-definitions-list" componentProps={{'serverUrl': serverUrl, culture: culture}} exact={true}/>
<stencil-route url="/workflow-definitions/:id" component="elsa-studio-workflow-definitions-edit" componentProps={{'serverUrl': serverUrl, culture: culture, 'monacoLibPath': monacoLibPath}}/>
<stencil-route url="/workflow-instances" component="elsa-studio-workflow-instances-list" componentProps={{'serverUrl': serverUrl, culture: culture}} exact={true}/>
<stencil-route url="/workflow-instances/:id" component="elsa-studio-workflow-instances-view" componentProps={{'serverUrl': serverUrl, culture: culture}}/>
<stencil-route url="/webhook-definitions" component="elsa-studio-webhook-definitions-list" componentProps={{'serverUrl': serverUrl, culture: culture}} exact={true}/>
<stencil-route url="/webhook-definitions/:id" component="elsa-studio-webhook-definitions-edit" componentProps={{'serverUrl': serverUrl, culture: culture}}/>
<stencil-route url={`${basePath}/`} component="elsa-studio-home" exact={true} componentProps={{culture: culture}}/>
<stencil-route url={`${basePath}/workflow-registry`} component="elsa-studio-workflow-registry" componentProps={{'serverUrl': serverUrl, culture: culture}} exact={true}/>
<stencil-route url={`${basePath}/workflow-registry/:id`} component="elsa-studio-workflow-blueprint-view" componentProps={{'serverUrl': serverUrl, culture: culture}}/>
<stencil-route url={`${basePath}/workflow-definitions`} component="elsa-studio-workflow-definitions-list" componentProps={{'serverUrl': serverUrl, culture: culture}} exact={true}/>
<stencil-route url={`${basePath}/workflow-definitions/:id`} component="elsa-studio-workflow-definitions-edit" componentProps={{'serverUrl': serverUrl, culture: culture, 'monacoLibPath': monacoLibPath}}/>
<stencil-route url={`${basePath}/workflow-instances`} component="elsa-studio-workflow-instances-list" componentProps={{'serverUrl': serverUrl, culture: culture}} exact={true}/>
<stencil-route url={`${basePath}/workflow-instances/:id`} component="elsa-studio-workflow-instances-view" componentProps={{'serverUrl': serverUrl, culture: culture}}/>
<stencil-route url={`${basePath}/webhook-definitions`} component="elsa-studio-webhook-definitions-list" componentProps={{'serverUrl': serverUrl, culture: culture}} exact={true}/>
<stencil-route url={`${basePath}/webhook-definitions/:id`} component="elsa-studio-webhook-definitions-edit" componentProps={{'serverUrl': serverUrl, culture: culture}}/>
</stencil-route-switch>
</stencil-router>
{/*</Tunnel.Provider>*/}
</main>
<elsa-external-events serverUrl={serverUrl}/>
</div>
);
}

View file

@ -9,6 +9,7 @@
| Property | Attribute | Description | Type | Default |
| --------------- | ----------------- | ----------- | -------- | ----------- |
| `basePath` | `base-path` | | `string` | `''` |
| `culture` | `culture` | | `string` | `undefined` |
| `monacoLibPath` | `monaco-lib-path` | | `string` | `undefined` |
| `serverUrl` | `server-url` | | `string` | `undefined` |

View file

@ -32,14 +32,16 @@
// Custom plugin that changes the icon of the ReadLine activity.
function CustomReadLinePlugin(elsaStudio) {
// Replace icon used for 'ReadLine' activity.
elsaStudio.activityIconProvider.register('ReadLine', `<span class="elsa-rounded-lg elsa-inline-flex elsa-p-3 elsa-bg-green-50 elsa-text-green-700 elsa-ring-4 elsa-ring-white">
<svg class="elsa-h-6 elsa-w-6" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z"/>
<path d="M4 12v-3a3 3 0 0 1 3 -3h13m-3 -3l3 3l-3 3"/>
<path d="M20 12v3a3 3 0 0 1 -3 3h-13m3 3l-3-3l3-3"/>
<path d="M11 11l1 -1v4"/>
</svg>
</span>`);
elsaStudio.activityIconProvider.register(
'ReadLine',
`<span class="elsa-rounded-lg elsa-inline-flex elsa-p-3 elsa-bg-green-50 elsa-text-green-700 elsa-ring-4 elsa-ring-white">
<svg class="elsa-h-6 elsa-w-6" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z"/>
<path d="M4 12v-3a3 3 0 0 1 3 -3h13m-3 -3l3 3l-3 3"/>
<path d="M20 12v3a3 3 0 0 1 -3 3h-13m3 3l-3-3l3-3"/>
<path d="M11 11l1 -1v4"/>
</svg>
</span>`);
}
// Custom plugin that adds a menu item to the bulk actions list on the workflow instance list view.
@ -47,12 +49,14 @@
const eventBus = elsaStudio.eventBus;
eventBus.on(EventTypes.WorkflowInstanceBulkActionsLoading, async e => {
e.bulkActions.push({name: 'Reset', text: 'Reset', handler: async () => {
if(!await confirmDialogService.show("Reset Workflows", "Are you sure you want to do this??"))
return;
alert('Resetting workflows!');
}});
e.bulkActions.push({
name: 'Reset', text: 'Reset', handler: async () => {
if (!await confirmDialogService.show("Reset Workflows", "Are you sure you want to do this??"))
return;
alert('Resetting workflows!');
}
});
})
}
@ -78,7 +82,7 @@
// Get a handle to the elsa-studio-root element.
const elsaStudioRoot = document.querySelector('elsa-studio-root');
// Configure Elsa.
(async () => {
// Wait until the component is available.

View file

@ -2,22 +2,21 @@
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Text.Encodings.Web" Version="5.0.1" />
<PackageReference Include="System.Text.Encodings.Web" Version="5.0.1"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\activities\Elsa.Activities.Email\Elsa.Activities.Email.csproj" />
<ProjectReference Include="..\..\..\..\activities\Elsa.Activities.Http\Elsa.Activities.Http.csproj" />
<ProjectReference Include="..\..\..\..\activities\Elsa.Activities.Temporal.Quartz\Elsa.Activities.Temporal.Quartz.csproj" />
<ProjectReference Include="..\..\..\..\core\Elsa\Elsa.csproj" />
<ProjectReference Include="..\..\..\..\designer\bindings\aspnet\Elsa.Designer.Components.Web\Elsa.Designer.Components.Web.csproj" />
<ProjectReference Include="..\..\..\..\persistence\Elsa.Persistence.EntityFramework\Elsa.Persistence.EntityFramework.Sqlite\Elsa.Persistence.EntityFramework.Sqlite.csproj" />
<ProjectReference Include="..\..\..\..\server\Elsa.Server.Api\Elsa.Server.Api.csproj" />
<ProjectReference Include="..\..\..\persistence\Elsa.Samples.Persistence.EntityFramework\Elsa.Samples.Persistence.EntityFramework.csproj" />
<ProjectReference Include="..\..\..\..\activities\Elsa.Activities.Email\Elsa.Activities.Email.csproj"/>
<ProjectReference Include="..\..\..\..\activities\Elsa.Activities.Http\Elsa.Activities.Http.csproj"/>
<ProjectReference Include="..\..\..\..\activities\Elsa.Activities.Temporal.Quartz\Elsa.Activities.Temporal.Quartz.csproj"/>
<ProjectReference Include="..\..\..\..\core\Elsa\Elsa.csproj"/>
<ProjectReference Include="..\..\..\..\designer\bindings\aspnet\Elsa.Designer.Components.Web\Elsa.Designer.Components.Web.csproj"/>
<ProjectReference Include="..\..\..\..\persistence\Elsa.Persistence.EntityFramework\Elsa.Persistence.EntityFramework.Sqlite\Elsa.Persistence.EntityFramework.Sqlite.csproj"/>
<ProjectReference Include="..\..\..\..\server\Elsa.Server.Api\Elsa.Server.Api.csproj"/>
<ProjectReference Include="..\..\..\persistence\Elsa.Samples.Persistence.EntityFramework\Elsa.Samples.Persistence.EntityFramework.csproj"/>
</ItemGroup>
</Project>

View file

@ -1,4 +1,3 @@
using System.Collections.Generic;
using Elsa;
using Elsa.Persistence.EntityFramework.Core.Extensions;
using Elsa.Persistence.EntityFramework.Sqlite;
@ -60,7 +59,6 @@ namespace ElsaDashboard.Samples.AspNetCore.Monolith
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}

View file

@ -10,7 +10,7 @@
"Elsa": {
"Features": [],
"Server": {
"BaseUrl": "https://localhost:15265",
"BaseUrl": "https://localhost:11000",
"BasePath": "/workflows"
}
}

View file

@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Text.Encodings.Web" Version="5.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\activities\Elsa.Activities.Email\Elsa.Activities.Email.csproj" />
<ProjectReference Include="..\..\..\..\activities\Elsa.Activities.Http\Elsa.Activities.Http.csproj" />
<ProjectReference Include="..\..\..\..\activities\Elsa.Activities.Temporal.Quartz\Elsa.Activities.Temporal.Quartz.csproj" />
<ProjectReference Include="..\..\..\..\core\Elsa\Elsa.csproj" />
<ProjectReference Include="..\..\..\..\designer\bindings\aspnet\Elsa.Designer.Components.Web\Elsa.Designer.Components.Web.csproj" />
<ProjectReference Include="..\..\..\..\persistence\Elsa.Persistence.EntityFramework\Elsa.Persistence.EntityFramework.Sqlite\Elsa.Persistence.EntityFramework.Sqlite.csproj" />
<ProjectReference Include="..\..\..\..\server\Elsa.Server.Api\Elsa.Server.Api.csproj" />
<ProjectReference Include="..\..\..\persistence\Elsa.Samples.Persistence.EntityFramework\Elsa.Samples.Persistence.EntityFramework.csproj" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,26 @@
@page "/Elsa/Dashboard"
@using Microsoft.Extensions.Configuration
@inject IConfiguration _configuration;
@{
Layout = null;
var serverUrl = _configuration["Elsa:Server:BaseUrl"];
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Elsa Dashboard</title>
<link rel="icon" type="image/png" sizes="32x32" href="/_content/Elsa.Designer.Components.Web/elsa-workflows-studio/assets/images/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/_content/Elsa.Designer.Components.Web/elsa-workflows-studio/assets/images/favicon-16x16.png">
<link rel="stylesheet" href="/_content/Elsa.Designer.Components.Web/elsa-workflows-studio/assets/fonts/inter/inter.css">
<link rel="stylesheet" href="/_content/Elsa.Designer.Components.Web/elsa-workflows-studio/assets/styles/tailwind.css">
<script src="/_content/Elsa.Designer.Components.Web/monaco-editor/min/vs/loader.js"></script>
<script type="module" src="/_content/Elsa.Designer.Components.Web/elsa-workflows-studio/elsa-workflows-studio.esm.js"></script>
</head>
<body>
<elsa-studio-root server-url="@serverUrl" monaco-lib-path="_content/Elsa.Designer.Components.Web/monaco-editor/min">
<elsa-studio-dashboard base-path="/elsa/dashboard"></elsa-studio-dashboard>
</elsa-studio-root>
</body>
</html>

View file

@ -0,0 +1,26 @@
@page
@model ErrorModel
@{
ViewData["Title"] = "Error";
}
<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>
@if (Model.ShowRequestId)
{
<p>
<strong>Request ID:</strong> <code>@Model.RequestId</code>
</p>
}
<h3>Development Mode</h3>
<p>
Swapping to the <strong>Development</strong> environment displays detailed information about the error that occurred.
</p>
<p>
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
It can result in displaying sensitive information from exceptions to end users.
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
and restarting the app.
</p>

View file

@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
namespace ElsaDashboard.Samples.AspNetCore.SubPath.Pages
{
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
[IgnoreAntiforgeryToken]
public class ErrorModel : PageModel
{
public string RequestId { get; set; }
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
private readonly ILogger<ErrorModel> _logger;
public ErrorModel(ILogger<ErrorModel> logger)
{
_logger = logger;
}
public void OnGet()
{
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
}
}
}

View file

@ -0,0 +1,10 @@
@page
@model IndexModel
@{
ViewData["Title"] = "Home page";
}
<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>

View file

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
namespace ElsaDashboard.Samples.AspNetCore.SubPath.Pages
{
public class IndexModel : PageModel
{
private readonly ILogger<IndexModel> _logger;
public IndexModel(ILogger<IndexModel> logger)
{
_logger = logger;
}
public void OnGet()
{
}
}
}

View file

@ -0,0 +1,8 @@
@page
@model PrivacyModel
@{
ViewData["Title"] = "Privacy Policy";
}
<h1>@ViewData["Title"]</h1>
<p>Use this page to detail your site's privacy policy.</p>

View file

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
namespace ElsaDashboard.Samples.AspNetCore.SubPath.Pages
{
public class PrivacyModel : PageModel
{
private readonly ILogger<PrivacyModel> _logger;
public PrivacyModel(ILogger<PrivacyModel> logger)
{
_logger = logger;
}
public void OnGet()
{
}
}
}

View file

@ -0,0 +1,50 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>@ViewData["Title"] - ElsaDashboard.Samples.AspNetCore.SubPath</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css"/>
<link rel="stylesheet" href="~/css/site.css"/>
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-area="" asp-page="/Index">ElsaDashboard.Samples.AspNetCore.SubPath</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Privacy">Privacy</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
&copy; 2021 - ElsaDashboard.Samples.AspNetCore.SubPath - <a asp-area="" asp-page="/Privacy">Privacy</a>
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>

View file

@ -0,0 +1,2 @@
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>

View file

@ -0,0 +1,3 @@
@using ElsaDashboard.Samples.AspNetCore.SubPath
@namespace ElsaDashboard.Samples.AspNetCore.SubPath.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

View file

@ -0,0 +1,3 @@
@{
Layout = "_Layout";
}

View file

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace ElsaDashboard.Samples.AspNetCore.SubPath
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });
}
}

View file

@ -0,0 +1,28 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:48783",
"sslPort": 44373
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"ElsaDashboard.Samples.AspNetCore.SubPath": {
"commandName": "Project",
"dotnetRunMessages": "true",
"launchBrowser": true,
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View file

@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Elsa;
using Elsa.Persistence.EntityFramework.Core.Extensions;
using Elsa.Persistence.EntityFramework.Sqlite;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace ElsaDashboard.Samples.AspNetCore.SubPath
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
// Elsa Server.
var elsaSection = Configuration.GetSection("Elsa");
services
.AddElsa(options => options
.UseEntityFrameworkPersistence(ef => ef.UseSqlite())
.AddConsoleActivities()
.AddHttpActivities(elsaSection.GetSection("Server").Bind)
.AddEmailActivities(elsaSection.GetSection("Smtp").Bind)
.AddQuartzTemporalActivities()
.AddJavaScriptActivities()
.AddActivitiesFrom<Startup>()
.AddFeatures(new[] { typeof(Startup) }, Configuration)
);
services
.AddElsaSwagger()
.AddElsaApiEndpoints();
// Allow arbitrary client browser apps to access the API.
// In a production environment, make sure to allow only origins you trust.
services.AddCors(cors => cors.AddDefaultPolicy(policy => policy.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin().WithExposedHeaders("Content-Disposition")));
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Elsa"));
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseCors();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseHttpActivities();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapControllers();
endpoints.MapFallbackToPage("/ElsaDashboard");
});
}
}
}

View file

@ -0,0 +1,17 @@
{
"Logging": {
"LogLevel": {
"Default": "Debug",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"Elsa": {
"Features": [],
"Server": {
"BaseUrl": "https://localhost:11000",
"BasePath": "/workflows"
}
}
}