Merge pull request #499 from sbwalker/master
Added support for module resource management
This commit is contained in:
commit
a13208e65d
@ -20,6 +20,26 @@
|
||||
}
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit;
|
||||
|
||||
public override string Title => "Edit Html/Text";
|
||||
|
||||
public override List<Resource> Resources
|
||||
{
|
||||
get
|
||||
{
|
||||
List<Resource> resources = new List<Resource>();
|
||||
resources.Add(new Resource { ResourceType = ResourceType.Stylesheet, Url = ModulePath() + "Module.css", Integrity = "", CrossOrigin = "" });
|
||||
// the following resources should be declared in the RichTextEditor component however the framework currently only supports resource management for modules and themes
|
||||
resources.Add(new Resource { ResourceType = ResourceType.Stylesheet, Url = "css/quill/quill1.3.6.bubble.css", Integrity = "", CrossOrigin = "" });
|
||||
resources.Add(new Resource { ResourceType = ResourceType.Stylesheet, Url = "css/quill/quill1.3.6.snow.css", Integrity = "", CrossOrigin = "" });
|
||||
resources.Add(new Resource { ResourceType = ResourceType.Script, Url = "js/quill1.3.6.min.js", Integrity = "", CrossOrigin = "" });
|
||||
resources.Add(new Resource { ResourceType = ResourceType.Script, Url = "js/quill-blot-formatter.min.js", Integrity = "", CrossOrigin = "" });
|
||||
resources.Add(new Resource { ResourceType = ResourceType.Script, Url = "js/quill-interop.js", Integrity = "", CrossOrigin = "" });
|
||||
return resources;
|
||||
}
|
||||
}
|
||||
|
||||
private RichTextEditor RichTextEditorHtml;
|
||||
private string _content = null;
|
||||
private string _createdby;
|
||||
@ -27,10 +47,6 @@
|
||||
private string _modifiedby;
|
||||
private DateTime _modifiedon;
|
||||
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit;
|
||||
|
||||
public override string Title => "Edit Html/Text";
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
try
|
||||
|
@ -11,6 +11,16 @@
|
||||
}
|
||||
|
||||
@code {
|
||||
public override List<Resource> Resources
|
||||
{
|
||||
get
|
||||
{
|
||||
List<Resource> resources = new List<Resource>();
|
||||
resources.Add(new Resource { ResourceType = ResourceType.Stylesheet, Url = ModulePath() + "Module.css", Integrity = "", CrossOrigin = "" });
|
||||
return resources;
|
||||
}
|
||||
}
|
||||
|
||||
private string content = "";
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
|
@ -6,6 +6,7 @@ using Oqtane.Services;
|
||||
using System;
|
||||
using Oqtane.Enums;
|
||||
using Oqtane.UI;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Oqtane.Modules
|
||||
{
|
||||
@ -37,6 +38,9 @@ namespace Oqtane.Modules
|
||||
|
||||
public virtual bool UseAdminContainer { get { return true; } }
|
||||
|
||||
public virtual List<Resource> Resources { get; set; }
|
||||
|
||||
|
||||
// path method
|
||||
|
||||
public string ModulePath()
|
||||
|
@ -33,7 +33,7 @@
|
||||
get
|
||||
{
|
||||
List<Resource> resources = new List<Resource>();
|
||||
resources.Add(new Resource { ResourceType = ResourceType.Stylesheet, Url = "Themes/" + GetType().Namespace + "/Theme.css", Integrity = "", CrossOrigin = "" });
|
||||
resources.Add(new Resource { ResourceType = ResourceType.Stylesheet, Url = ThemePath() + "Theme.css", Integrity = "", CrossOrigin = "" });
|
||||
return resources;
|
||||
}
|
||||
}
|
||||
|
@ -149,7 +149,7 @@
|
||||
<label for="Pane" class="control-label">Pane: </label>
|
||||
<select class="form-control" @bind="@_pane">
|
||||
<option value=""><Select Pane></option>
|
||||
@foreach (string pane in PageState.Page.Panes.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
|
||||
@foreach (string pane in PageState.Page.Panes)
|
||||
{
|
||||
<option value="@pane">@pane Pane</option>
|
||||
}
|
||||
@ -275,7 +275,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
var panes = PageState.Page.Panes.Split(new[] {';'}, StringSplitOptions.RemoveEmptyEntries);
|
||||
var panes = PageState.Page.Panes;
|
||||
_pane = panes.Count() == 1 ? panes.SingleOrDefault() : "";
|
||||
var themes = await ThemeService.GetThemesAsync();
|
||||
_containers = ThemeService.GetContainerTypes(themes);
|
||||
|
@ -60,7 +60,7 @@ namespace Oqtane.Themes.Controls
|
||||
actionList.Add(new ActionViewModel {Name = "Move To Bottom", Action = async (s, m) => await MoveBottom(s, m)});
|
||||
}
|
||||
|
||||
foreach (string pane in PageState.Page.Panes.Split(new[] {';'}, StringSplitOptions.RemoveEmptyEntries))
|
||||
foreach (string pane in PageState.Page.Panes)
|
||||
{
|
||||
if (pane != ModuleState.Pane)
|
||||
{
|
||||
|
@ -25,7 +25,7 @@
|
||||
{
|
||||
List<Resource> resources = new List<Resource>();
|
||||
resources.Add(new Resource { ResourceType = ResourceType.Stylesheet, Url = "https://stackpath.bootstrapcdn.com/bootswatch/4.4.1/cyborg/bootstrap.min.css", Integrity = "sha384-l7xaoY0cJM4h9xh1RfazbgJVUZvdtyLWPueWNtLAphf/UbBgOVzqbOTogxPwYLHM", CrossOrigin = "anonymous" });
|
||||
resources.Add(new Resource { ResourceType = ResourceType.Stylesheet, Url = "Themes/" + GetType().Namespace + "/Theme.css", Integrity = "", CrossOrigin = "" });
|
||||
resources.Add(new Resource { ResourceType = ResourceType.Stylesheet, Url = ThemePath() + "Theme.css", Integrity = "", CrossOrigin = "" });
|
||||
return resources;
|
||||
}
|
||||
}
|
||||
|
@ -238,21 +238,7 @@
|
||||
{
|
||||
page = await ProcessPage(page, site, user);
|
||||
|
||||
_pagestate = new PageState
|
||||
{
|
||||
Alias = alias,
|
||||
Site = site,
|
||||
Pages = pages,
|
||||
Page = page,
|
||||
User = user,
|
||||
Uri = new Uri(_absoluteUri, UriKind.Absolute),
|
||||
QueryString = querystring,
|
||||
ModuleId = moduleid,
|
||||
Action = action,
|
||||
Runtime = runtime
|
||||
};
|
||||
|
||||
if (PageState != null && (PageState.ModuleId != _pagestate.ModuleId || PageState.Action != _pagestate.Action))
|
||||
if (PageState != null && (PageState.ModuleId != moduleid || PageState.Action != action))
|
||||
{
|
||||
reload = Reload.Page;
|
||||
}
|
||||
@ -260,15 +246,29 @@
|
||||
if (PageState == null || reload >= Reload.Page)
|
||||
{
|
||||
modules = await ModuleService.GetModulesAsync(site.SiteId);
|
||||
modules = ProcessModules(modules, page.PageId, _pagestate.ModuleId, _pagestate.Action, page.Panes, (!string.IsNullOrEmpty(page.DefaultContainerType)) ? page.DefaultContainerType : site.DefaultContainerType);
|
||||
(page, modules) = ProcessModules(page, modules, moduleid, action, (!string.IsNullOrEmpty(page.DefaultContainerType)) ? page.DefaultContainerType : site.DefaultContainerType);
|
||||
}
|
||||
else
|
||||
{
|
||||
modules = PageState.Modules;
|
||||
}
|
||||
_pagestate.Modules = modules;
|
||||
_pagestate.EditMode = editmode;
|
||||
_pagestate.LastSyncDate = lastsyncdate;
|
||||
|
||||
_pagestate = new PageState
|
||||
{
|
||||
Alias = alias,
|
||||
Site = site,
|
||||
Pages = pages,
|
||||
Page = page,
|
||||
User = user,
|
||||
Modules = modules,
|
||||
Uri = new Uri(_absoluteUri, UriKind.Absolute),
|
||||
QueryString = querystring,
|
||||
ModuleId = moduleid,
|
||||
Action = action,
|
||||
EditMode = editmode,
|
||||
LastSyncDate = lastsyncdate,
|
||||
Runtime = runtime
|
||||
};
|
||||
|
||||
OnStateChange?.Invoke(_pagestate);
|
||||
}
|
||||
@ -356,18 +356,17 @@
|
||||
page.LayoutType = site.DefaultLayoutType;
|
||||
}
|
||||
|
||||
page.Panes = new List<string>();
|
||||
page.Resources = new List<Resource>();
|
||||
|
||||
string panes = "";
|
||||
Type themetype = Type.GetType(page.ThemeType);
|
||||
var themeobject = Activator.CreateInstance(themetype);
|
||||
if (themeobject != null)
|
||||
{
|
||||
page.Panes = (string)themetype.GetProperty("Panes").GetValue(themeobject, null);
|
||||
panes = (string)themetype.GetProperty("Panes").GetValue(themeobject, null);
|
||||
var resources = (List<Resource>)themetype.GetProperty("Resources").GetValue(themeobject, null);
|
||||
if (resources != null)
|
||||
{
|
||||
page.Resources.AddRange(resources);
|
||||
}
|
||||
page.Resources = ManagePageResources(page.Resources, resources);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(page.LayoutType))
|
||||
@ -376,9 +375,11 @@
|
||||
themeobject = Activator.CreateInstance(themetype);
|
||||
if (themeobject != null)
|
||||
{
|
||||
page.Panes = (string)themetype.GetProperty("Panes").GetValue(themeobject, null);
|
||||
panes = (string)themetype.GetProperty("Panes").GetValue(themeobject, null);
|
||||
}
|
||||
}
|
||||
|
||||
page.Panes = panes.Replace(";", ",").Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList();
|
||||
}
|
||||
catch
|
||||
{
|
||||
@ -388,12 +389,12 @@
|
||||
return page;
|
||||
}
|
||||
|
||||
private List<Module> ProcessModules(List<Module> modules, int pageid, int moduleid, string control, string panes, string defaultcontainertype)
|
||||
private (Page Page, List<Module> Modules) ProcessModules(Page page, List<Module> modules, int moduleid, string control, string defaultcontainertype)
|
||||
{
|
||||
var paneindex = new Dictionary<string, int>();
|
||||
foreach (Module module in modules)
|
||||
{
|
||||
if (module.PageId == pageid || module.ModuleId == moduleid)
|
||||
if (module.PageId == page.PageId || module.ModuleId == moduleid)
|
||||
{
|
||||
var typename = string.Empty;
|
||||
if (module.ModuleDefinition != null)
|
||||
@ -419,49 +420,53 @@
|
||||
}
|
||||
}
|
||||
module.ModuleType = typename.Replace(Constants.ActionToken, control);
|
||||
|
||||
// admin controls need to load additional metadata from the IModuleControl interface
|
||||
if (moduleid == module.ModuleId)
|
||||
{
|
||||
typename = module.ModuleType;
|
||||
// check for core module actions component
|
||||
if (Constants.DefaultModuleActions.Contains(control))
|
||||
{
|
||||
typename = Constants.DefaultModuleActionsTemplate.Replace(Constants.ActionToken, control);
|
||||
}
|
||||
Type moduletype = Type.GetType(typename);
|
||||
if (moduletype != null)
|
||||
{
|
||||
var moduleobject = Activator.CreateInstance(moduletype);
|
||||
module.SecurityAccessLevel = (SecurityAccessLevel)moduletype.GetProperty("SecurityAccessLevel").GetValue(moduleobject, null);
|
||||
module.ControlTitle = (string)moduletype.GetProperty("Title").GetValue(moduleobject);
|
||||
module.Actions = (string)moduletype.GetProperty("Actions").GetValue(moduleobject);
|
||||
module.UseAdminContainer = (bool)moduletype.GetProperty("UseAdminContainer").GetValue(moduleobject);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
module.ModuleType = typename.Replace(Constants.ActionToken, Constants.DefaultAction);
|
||||
}
|
||||
|
||||
// get additional metadata from IModuleControl interface
|
||||
typename = module.ModuleType;
|
||||
if (Constants.DefaultModuleActions.Contains(control))
|
||||
{
|
||||
// core framework module action components
|
||||
typename = Constants.DefaultModuleActionsTemplate.Replace(Constants.ActionToken, control);
|
||||
}
|
||||
Type moduletype = Type.GetType(typename);
|
||||
if (moduletype != null)
|
||||
{
|
||||
var moduleobject = Activator.CreateInstance(moduletype);
|
||||
var resources = (List<Resource>)moduletype.GetProperty("Resources").GetValue(moduleobject, null);
|
||||
page.Resources = ManagePageResources(page.Resources, resources);
|
||||
|
||||
// additional metadata needed for admin components
|
||||
if (module.ModuleId == moduleid && control != "")
|
||||
{
|
||||
module.SecurityAccessLevel = (SecurityAccessLevel)moduletype.GetProperty("SecurityAccessLevel").GetValue(moduleobject, null);
|
||||
module.ControlTitle = (string)moduletype.GetProperty("Title").GetValue(moduleobject);
|
||||
module.Actions = (string)moduletype.GetProperty("Actions").GetValue(moduleobject);
|
||||
module.UseAdminContainer = (bool)moduletype.GetProperty("UseAdminContainer").GetValue(moduleobject);
|
||||
}
|
||||
}
|
||||
|
||||
// ensure module's pane exists in current page and if not, assign it to the Admin pane
|
||||
if (panes == null || !panes.ToLower().Contains(module.Pane.ToLower()))
|
||||
if (page.Panes == null || page.Panes.FindIndex(item => item.Equals(module.Pane, StringComparison.OrdinalIgnoreCase)) == -1)
|
||||
{
|
||||
module.Pane = Constants.AdminPane;
|
||||
}
|
||||
|
||||
// calculate module position within pane
|
||||
if (paneindex.ContainsKey(module.Pane))
|
||||
if (paneindex.ContainsKey(module.Pane.ToLower()))
|
||||
{
|
||||
paneindex[module.Pane] += 1;
|
||||
paneindex[module.Pane.ToLower()] += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
paneindex.Add(module.Pane, 0);
|
||||
paneindex.Add(module.Pane.ToLower(), 0);
|
||||
}
|
||||
|
||||
module.PaneModuleIndex = paneindex[module.Pane];
|
||||
module.PaneModuleIndex = paneindex[module.Pane.ToLower()];
|
||||
|
||||
if (string.IsNullOrEmpty(module.ContainerType))
|
||||
{
|
||||
@ -470,16 +475,32 @@
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Module module in modules.Where(item => item.PageId == pageid))
|
||||
foreach (Module module in modules.Where(item => item.PageId == page.PageId))
|
||||
{
|
||||
module.PaneModuleCount = paneindex[module.Pane] + 1;
|
||||
module.PaneModuleCount = paneindex[module.Pane.ToLower()] + 1;
|
||||
}
|
||||
|
||||
return modules;
|
||||
return (page, modules);
|
||||
}
|
||||
|
||||
private List<Resource> ManagePageResources(List<Resource> pageresources, List<Resource> resources)
|
||||
{
|
||||
if (resources != null)
|
||||
{
|
||||
foreach (var resource in resources)
|
||||
{
|
||||
// ensure resource does not exist already
|
||||
if (pageresources.Find(item => item.Url == resource.Url) == null)
|
||||
{
|
||||
pageresources.Add(resource);
|
||||
}
|
||||
}
|
||||
}
|
||||
return pageresources;
|
||||
}
|
||||
|
||||
private Runtime GetRuntime()
|
||||
=> RuntimeInformation.IsOSPlatform(OSPlatform.Create("BROWSER"))
|
||||
? Runtime.WebAssembly
|
||||
: Runtime.Server;
|
||||
=> RuntimeInformation.IsOSPlatform(OSPlatform.Create("BROWSER"))
|
||||
? Runtime.WebAssembly
|
||||
: Runtime.Server;
|
||||
}
|
||||
|
@ -23,22 +23,26 @@
|
||||
await interop.UpdateTitle(PageState.Site.Name + " - " + PageState.Page.Name);
|
||||
}
|
||||
|
||||
// manage page resources- they cannot be removed first and then added because the browser will "flash" and result in a poor user experience - they need to be updated
|
||||
int index = 0;
|
||||
// update page resources
|
||||
int stylesheet = 0;
|
||||
int script = 0;
|
||||
foreach (Resource resource in PageState.Page.Resources)
|
||||
{
|
||||
index += 1;
|
||||
switch (resource.ResourceType)
|
||||
{
|
||||
case ResourceType.Stylesheet:
|
||||
await interop.IncludeLink("app-resource" + index.ToString("00"), "stylesheet", resource.Url, "text/css", resource.Integrity, resource.CrossOrigin);
|
||||
stylesheet += 1;
|
||||
await interop.IncludeLink("app-stylesheet" + stylesheet.ToString("00"), "stylesheet", resource.Url, "text/css", resource.Integrity ?? "", resource.CrossOrigin ?? "");
|
||||
break;
|
||||
case ResourceType.Script:
|
||||
script += 1;
|
||||
await interop.IncludeScript("app-script" + script.ToString("00"), resource.Url, "", "body", resource.Integrity ?? "", resource.CrossOrigin ?? "");
|
||||
break;
|
||||
}
|
||||
}
|
||||
// remove any page resources references which are no longer required for this page
|
||||
await interop.RemoveElementsById("app-resource", "app-resource" + (index + 1).ToString("00"), "");
|
||||
await interop.RemoveElementsById("app-stylesheet", "app-stylesheet" + (stylesheet + 1).ToString("00"), "");
|
||||
await interop.RemoveElementsById("app-script", "app-script" + (script + 1).ToString("00"), "");
|
||||
|
||||
// add favicon
|
||||
if (PageState.Site.FaviconFileId != null)
|
||||
|
@ -14,8 +14,6 @@
|
||||
<link id="fav-icon" rel="shortcut icon" type="image/x-icon" href="favicon.ico" />
|
||||
<!-- stub the PWA manifest but defer the assignment of href -->
|
||||
<link id="pwa-manifest" rel="manifest" />
|
||||
<link href="css/quill/quill1.3.6.bubble.css" rel="stylesheet" />
|
||||
<link href="css/quill/quill1.3.6.snow.css" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
|
||||
<link href="css/app.css" rel="stylesheet" />
|
||||
</head>
|
||||
@ -25,10 +23,7 @@
|
||||
<component type="typeof(Oqtane.App)" render-mode="Server" />
|
||||
</app>
|
||||
|
||||
<script src="js/site.js"></script>
|
||||
<script src="js/interop.js"></script>
|
||||
<script src="js/quill1.3.6.min.js"></script>
|
||||
<script src="js/quill-blot-formatter.min.js"></script>
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
|
||||
|
@ -0,0 +1 @@
|
||||
/* HtmlText Module Custom Styles */
|
@ -264,53 +264,5 @@ window.interop = {
|
||||
request.send(data);
|
||||
}
|
||||
}
|
||||
},
|
||||
createQuill: function (
|
||||
quillElement, toolBar, readOnly,
|
||||
placeholder, theme, debugLevel) {
|
||||
|
||||
Quill.register('modules/blotFormatter', QuillBlotFormatter.default);
|
||||
|
||||
var options = {
|
||||
debug: debugLevel,
|
||||
modules: {
|
||||
toolbar: toolBar,
|
||||
blotFormatter: {}
|
||||
},
|
||||
placeholder: placeholder,
|
||||
readOnly: readOnly,
|
||||
theme: theme
|
||||
};
|
||||
|
||||
new Quill(quillElement, options);
|
||||
},
|
||||
getQuillContent: function (editorElement) {
|
||||
return JSON.stringify(editorElement.__quill.getContents());
|
||||
},
|
||||
getQuillText: function (editorElement) {
|
||||
return editorElement.__quill.getText();
|
||||
},
|
||||
getQuillHTML: function (editorElement) {
|
||||
return editorElement.__quill.root.innerHTML;
|
||||
},
|
||||
loadQuillContent: function (editorElement, editorContent) {
|
||||
return editorElement.__quill.root.innerHTML = editorContent;
|
||||
},
|
||||
enableQuillEditor: function (editorElement, mode) {
|
||||
editorElement.__quill.enable(mode);
|
||||
},
|
||||
insertQuillImage: function (quillElement, imageURL) {
|
||||
var Delta = Quill.import('delta');
|
||||
editorIndex = 0;
|
||||
|
||||
if (quillElement.__quill.getSelection() !== null) {
|
||||
editorIndex = quillElement.__quill.getSelection().index;
|
||||
}
|
||||
|
||||
return quillElement.__quill.updateContents(
|
||||
new Delta()
|
||||
.retain(editorIndex)
|
||||
.insert({ image: imageURL },
|
||||
{ alt: imageURL }));
|
||||
}
|
||||
};
|
||||
|
50
Oqtane.Server/wwwroot/js/quill-interop.js
Normal file
50
Oqtane.Server/wwwroot/js/quill-interop.js
Normal file
@ -0,0 +1,50 @@
|
||||
window.interop = {
|
||||
createQuill: function (
|
||||
quillElement, toolBar, readOnly,
|
||||
placeholder, theme, debugLevel) {
|
||||
|
||||
Quill.register('modules/blotFormatter', QuillBlotFormatter.default);
|
||||
|
||||
var options = {
|
||||
debug: debugLevel,
|
||||
modules: {
|
||||
toolbar: toolBar,
|
||||
blotFormatter: {}
|
||||
},
|
||||
placeholder: placeholder,
|
||||
readOnly: readOnly,
|
||||
theme: theme
|
||||
};
|
||||
|
||||
new Quill(quillElement, options);
|
||||
},
|
||||
getQuillContent: function (editorElement) {
|
||||
return JSON.stringify(editorElement.__quill.getContents());
|
||||
},
|
||||
getQuillText: function (editorElement) {
|
||||
return editorElement.__quill.getText();
|
||||
},
|
||||
getQuillHTML: function (editorElement) {
|
||||
return editorElement.__quill.root.innerHTML;
|
||||
},
|
||||
loadQuillContent: function (editorElement, editorContent) {
|
||||
return editorElement.__quill.root.innerHTML = editorContent;
|
||||
},
|
||||
enableQuillEditor: function (editorElement, mode) {
|
||||
editorElement.__quill.enable(mode);
|
||||
},
|
||||
insertQuillImage: function (quillElement, imageURL) {
|
||||
var Delta = Quill.import('delta');
|
||||
editorIndex = 0;
|
||||
|
||||
if (quillElement.__quill.getSelection() !== null) {
|
||||
editorIndex = quillElement.__quill.getSelection().index;
|
||||
}
|
||||
|
||||
return quillElement.__quill.updateContents(
|
||||
new Delta()
|
||||
.retain(editorIndex)
|
||||
.insert({ image: imageURL },
|
||||
{ alt: imageURL }));
|
||||
}
|
||||
};
|
@ -1 +0,0 @@
|
||||
|
@ -1,4 +1,6 @@
|
||||
using Oqtane.Shared;
|
||||
using Oqtane.Models;
|
||||
using Oqtane.Shared;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Oqtane.Modules
|
||||
{
|
||||
@ -8,5 +10,6 @@ namespace Oqtane.Modules
|
||||
string Title { get; } // title to display for this control - defaults to module title
|
||||
string Actions { get; } // allows for routing by configuration rather than by convention ( comma delimited ) - defaults to using component file name
|
||||
bool UseAdminContainer { get; } // container for embedding module control - defaults to true. false will suppress the default modal UI popup behavior and render the component in the page.
|
||||
List<Resource> Resources { get; } // identifies all resources in a module
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ namespace Oqtane.Models
|
||||
public bool IsDeleted { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public string Panes { get; set; }
|
||||
public List<string> Panes { get; set; }
|
||||
[NotMapped]
|
||||
public List<Resource> Resources { get; set; }
|
||||
[NotMapped]
|
||||
|
Reference in New Issue
Block a user