Merge pull request #315 from sbwalker/master
Added Favicon support, Progressive Web Apps, page title and urls, and private/public user registration
This commit is contained in:
		| @ -15,6 +15,14 @@ | ||||
|                 <input class="form-control" @bind="@_name" /> | ||||
|             </td> | ||||
|         </tr> | ||||
|         <tr> | ||||
|             <td> | ||||
|                 <label for="Title" class="control-label">Title: </label> | ||||
|             </td> | ||||
|             <td> | ||||
|                 <input class="form-control" @bind="@_title" /> | ||||
|             </td> | ||||
|         </tr> | ||||
|         <tr> | ||||
|             <td> | ||||
|                 <label for="Name" class="control-label">Path: </label> | ||||
| @ -74,6 +82,14 @@ | ||||
|                 </select> | ||||
|             </td> | ||||
|         </tr> | ||||
|         <tr> | ||||
|             <td> | ||||
|                 <label for="Url" class="control-label">Url: </label> | ||||
|             </td> | ||||
|             <td> | ||||
|                 <input class="form-control" @bind="@_url" /> | ||||
|             </td> | ||||
|         </tr> | ||||
|         <tr> | ||||
|             <td> | ||||
|                 <label for="Name" class="control-label">Personalizable? </label> | ||||
| @ -151,12 +167,14 @@ | ||||
|  | ||||
|     List<Theme> _themeList; | ||||
|     List<Page> _pageList; | ||||
|     string _name; | ||||
|     string _name = ""; | ||||
|     string _title = ""; | ||||
|     string _path = ""; | ||||
|     string _parentid; | ||||
|     string _insert = ">>"; | ||||
|     List<Page> _children; | ||||
|     int _childid = -1; | ||||
|     string _url = ""; | ||||
|     string _isnavigation = "True"; | ||||
|     string _ispersonalizable = "False"; | ||||
|     string _mode = "view"; | ||||
| @ -244,6 +262,7 @@ | ||||
|                 page = new Page(); | ||||
|                 page.SiteId = PageState.Page.SiteId; | ||||
|                 page.Name = _name; | ||||
|                 page.Title = _title; | ||||
|                 if (_path == "") | ||||
|                 { | ||||
|                     _path = _name; | ||||
| @ -289,6 +308,7 @@ | ||||
|                         break; | ||||
|                 } | ||||
|                 page.IsNavigation = (_isnavigation == null ? true : Boolean.Parse(_isnavigation)); | ||||
|                 page.Url = _url; | ||||
|                 page.EditMode = (_mode == "edit" ? true : false); | ||||
|                 page.ThemeType = _themetype; | ||||
|                 page.LayoutType = (_layouttype == null ? "" : _layouttype); | ||||
|  | ||||
| @ -15,6 +15,14 @@ | ||||
|                 <input class="form-control" @bind="@_name" /> | ||||
|             </td> | ||||
|         </tr> | ||||
|         <tr> | ||||
|             <td> | ||||
|                 <label for="Title" class="control-label">Title: </label> | ||||
|             </td> | ||||
|             <td> | ||||
|                 <input class="form-control" @bind="@_title" /> | ||||
|             </td> | ||||
|         </tr> | ||||
|         <tr> | ||||
|             <td> | ||||
|                 <label for="Name" class="control-label">Path: </label> | ||||
| @ -74,6 +82,14 @@ | ||||
|                 } | ||||
|             </td> | ||||
|         </tr> | ||||
|         <tr> | ||||
|             <td> | ||||
|                 <label for="Url" class="control-label">Url: </label> | ||||
|             </td> | ||||
|             <td> | ||||
|                 <input class="form-control" @bind="@_url" /> | ||||
|             </td> | ||||
|         </tr> | ||||
|         <tr> | ||||
|             <td> | ||||
|                 <label for="Name" class="control-label">Navigation? </label> | ||||
| @ -153,7 +169,7 @@ | ||||
|         <tr> | ||||
|             <td colspan="2" align="center"> | ||||
|                 <label for="Name" class="control-label">Permissions: </label> | ||||
|                  <PermissionGrid EntityName="@EntityNames.Page" Permissions="@_permissions" @ref="_permissionGrid" /> | ||||
|                 <PermissionGrid EntityName="@EntityNames.Page" Permissions="@_permissions" @ref="_permissionGrid" /> | ||||
|             </td> | ||||
|         </tr> | ||||
|     </table> | ||||
| @ -173,14 +189,16 @@ | ||||
|     List<Theme> _themeList; | ||||
|     List<Page> _pageList; | ||||
|     int _pageId; | ||||
|     string _name; | ||||
|     string _path; | ||||
|     string _name = ""; | ||||
|     string _title = ""; | ||||
|     string _path = ""; | ||||
|     string _currentparentid; | ||||
|     string _parentid; | ||||
|     string _insert = "="; | ||||
|     List<Page> _children; | ||||
|     int _childid = -1; | ||||
|     string _isnavigation; | ||||
|     string _url = ""; | ||||
|     string _ispersonalizable; | ||||
|     string _mode; | ||||
|     string _themetype; | ||||
| @ -213,6 +231,7 @@ | ||||
|             if (page != null) | ||||
|             { | ||||
|                 _name = page.Name; | ||||
|                 _title = page.Title; | ||||
|                 _path = page.Path; | ||||
|                 if (_path.Contains("/")) | ||||
|                 { | ||||
| @ -228,6 +247,7 @@ | ||||
|                 } | ||||
|                 _currentparentid = _parentid; | ||||
|                 _isnavigation = page.IsNavigation.ToString(); | ||||
|                 _url = page.Url; | ||||
|                 _ispersonalizable = page.IsPersonalizable.ToString(); | ||||
|                 _mode = (page.EditMode) ? "edit" : "view"; | ||||
|                 _themetype = page.ThemeType; | ||||
| @ -313,6 +333,7 @@ | ||||
|                 string currentPath = page.Path; | ||||
|  | ||||
|                 page.Name = _name; | ||||
|                 page.Title = _title; | ||||
|                 if (_path == "" && _name.ToLower() != "home") | ||||
|                 { | ||||
|                     _path = _name; | ||||
| @ -361,6 +382,7 @@ | ||||
|                     } | ||||
|                 } | ||||
|                 page.IsNavigation = (_isnavigation == null || Boolean.Parse(_isnavigation)); | ||||
|                 page.Url = _url; | ||||
|                 page.EditMode = (_mode == "edit"); | ||||
|                 page.ThemeType = _themetype; | ||||
|                 page.LayoutType = _layouttype ?? ""; | ||||
|  | ||||
| @ -12,7 +12,7 @@ | ||||
|     <table class="table table-borderless"> | ||||
|         <tr> | ||||
|             <td> | ||||
|                 <label  class="control-label">Name: </label> | ||||
|                 <label class="control-label">Name: </label> | ||||
|             </td> | ||||
|             <td> | ||||
|                 <input class="form-control" @bind="@_name" /> | ||||
| @ -20,7 +20,7 @@ | ||||
|         </tr> | ||||
|         <tr> | ||||
|             <td> | ||||
|                 <label  class="control-label">Tenant: </label> | ||||
|                 <label class="control-label">Tenant: </label> | ||||
|             </td> | ||||
|             <td> | ||||
|                 <input class="form-control" @bind="@_tenant" readonly /> | ||||
| @ -28,7 +28,7 @@ | ||||
|         </tr> | ||||
|         <tr> | ||||
|             <td> | ||||
|                 <label  class="control-label">Aliases: </label> | ||||
|                 <label class="control-label">Aliases: </label> | ||||
|             </td> | ||||
|             <td> | ||||
|                 <textarea class="form-control" @bind="@_urls" rows="3"></textarea> | ||||
| @ -36,15 +36,23 @@ | ||||
|         </tr> | ||||
|         <tr> | ||||
|             <td> | ||||
|                 <label  class="control-label">Logo: </label> | ||||
|                 <label class="control-label">Logo: </label> | ||||
|             </td> | ||||
|             <td> | ||||
|                 <FileManager FileId="@_logofileid.ToString()" @ref="_filemanager" /> | ||||
|                 <FileManager FileId="@_logofileid.ToString()" Filter="@Constants.ImageFiles" @ref="_logofilemanager" /> | ||||
|             </td> | ||||
|         </tr> | ||||
|         <tr> | ||||
|             <td> | ||||
|                 <label  class="control-label">Default Theme: </label> | ||||
|                 <label class="control-label">Favicon: </label> | ||||
|             </td> | ||||
|             <td> | ||||
|                 <FileManager FileId="@_faviconfileid.ToString()" Filter="ico" @ref="_faviconfilemanager" /> | ||||
|             </td> | ||||
|         </tr> | ||||
|         <tr> | ||||
|             <td> | ||||
|                 <label class="control-label">Default Theme: </label> | ||||
|             </td> | ||||
|             <td> | ||||
|                 <select class="form-control" @onchange="(e => ThemeChanged(e))"> | ||||
| @ -65,7 +73,7 @@ | ||||
|         </tr> | ||||
|         <tr> | ||||
|             <td> | ||||
|                 <label  class="control-label">Default Layout: </label> | ||||
|                 <label class="control-label">Default Layout: </label> | ||||
|             </td> | ||||
|             <td> | ||||
|                 <select class="form-control" @bind="@_layouttype"> | ||||
| @ -79,7 +87,7 @@ | ||||
|         </tr> | ||||
|         <tr> | ||||
|             <td> | ||||
|                 <label  class="control-label">Default Container: </label> | ||||
|                 <label class="control-label">Default Container: </label> | ||||
|             </td> | ||||
|             <td> | ||||
|                 <select class="form-control" @bind="@_containertype"> | ||||
| @ -93,7 +101,18 @@ | ||||
|         </tr> | ||||
|         <tr> | ||||
|             <td> | ||||
|                 <label  class="control-label">Is Deleted? </label> | ||||
|                 <label class="control-label">Allow User Registration? </label> | ||||
|             </td> | ||||
|             <td> | ||||
|                 <select class="form-control" @bind="@_allowregistration"> | ||||
|                     <option value="True">Yes</option> | ||||
|                     <option value="False">No</option> | ||||
|                 </select> | ||||
|             </td> | ||||
|         </tr> | ||||
|         <tr> | ||||
|             <td> | ||||
|                 <label class="control-label">Is Deleted? </label> | ||||
|             </td> | ||||
|             <td> | ||||
|                 <select class="form-control" @bind="@_isdeleted"> | ||||
| @ -111,7 +130,7 @@ | ||||
|         <table class="table table-borderless"> | ||||
|             <tr> | ||||
|                 <td> | ||||
|                     <label  class="control-label">Host: </label> | ||||
|                     <label class="control-label">Host: </label> | ||||
|                 </td> | ||||
|                 <td> | ||||
|                     <input class="form-control" @bind="@_smtphost" /> | ||||
| @ -119,7 +138,7 @@ | ||||
|             </tr> | ||||
|             <tr> | ||||
|                 <td> | ||||
|                     <label  class="control-label">Port: </label> | ||||
|                     <label class="control-label">Port: </label> | ||||
|                 </td> | ||||
|                 <td> | ||||
|                     <input class="form-control" @bind="@_smtpport" /> | ||||
| @ -127,7 +146,7 @@ | ||||
|             </tr> | ||||
|             <tr> | ||||
|                 <td> | ||||
|                     <label  class="control-label">SSL Enabled: </label> | ||||
|                     <label class="control-label">SSL Enabled: </label> | ||||
|                 </td> | ||||
|                 <td> | ||||
|                     <input class="form-control" @bind="@_smtpssl" /> | ||||
| @ -135,7 +154,7 @@ | ||||
|             </tr> | ||||
|             <tr> | ||||
|                 <td> | ||||
|                     <label  class="control-label">Username: </label> | ||||
|                     <label class="control-label">Username: </label> | ||||
|                 </td> | ||||
|                 <td> | ||||
|                     <input class="form-control" @bind="@_smtpusername" /> | ||||
| @ -143,7 +162,7 @@ | ||||
|             </tr> | ||||
|             <tr> | ||||
|                 <td> | ||||
|                     <label  class="control-label">Password: </label> | ||||
|                     <label class="control-label">Password: </label> | ||||
|                 </td> | ||||
|                 <td> | ||||
|                     <input type="password" class="form-control" @bind="@_smtppassword" /> | ||||
| @ -151,6 +170,43 @@ | ||||
|             </tr> | ||||
|         </table> | ||||
|     </div> | ||||
|  | ||||
|     <a data-toggle="collapse" class="app-link-unstyled" href="#PWA" aria-expanded="false" aria-controls="PWA"> | ||||
|         <h5><i class="oi oi-chevron-bottom"></i> Progressive Web Application Settings</h5><hr class="app-rule" /> | ||||
|     </a> | ||||
|     <div class="collapse" id="PWA"> | ||||
|         <table class="table table-borderless"> | ||||
|             <tr> | ||||
|                 <td> | ||||
|                     <label class="control-label">Is Enabled? </label> | ||||
|                 </td> | ||||
|                 <td> | ||||
|                     <select class="form-control" @bind="@_pwaisenabled"> | ||||
|                         <option value="True">Yes</option> | ||||
|                         <option value="False">No</option> | ||||
|                     </select> | ||||
|                 </td> | ||||
|             </tr> | ||||
|             <tr> | ||||
|                 <td> | ||||
|                     <label class="control-label">App Icon: </label> | ||||
|                 </td> | ||||
|                 <td> | ||||
|                     <FileManager FileId="@_pwaappiconfileid.ToString()" Filter="png" @ref="_pwaappiconfilemanager" /> | ||||
|                 </td> | ||||
|             </tr> | ||||
|             <tr> | ||||
|                 <td> | ||||
|                     <label class="control-label">Splash Icon: </label> | ||||
|                 </td> | ||||
|                 <td> | ||||
|                     <FileManager FileId="@_pwasplashiconfileid.ToString()" Filter="png" @ref="_pwasplashiconfilemanager" /> | ||||
|                 </td> | ||||
|             </tr> | ||||
|  | ||||
|         </table> | ||||
|     </div> | ||||
|  | ||||
|     <br /> | ||||
|     <button type="button" class="btn btn-success" @onclick="SaveSite">Save</button> | ||||
|     <NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink> | ||||
| @ -173,10 +229,13 @@ | ||||
|     List<Alias> _aliasList; | ||||
|     string _urls = ""; | ||||
|     int _logofileid = -1; | ||||
|     FileManager _filemanager; | ||||
|     FileManager _logofilemanager; | ||||
|     int _faviconfileid = -1; | ||||
|     FileManager _faviconfilemanager; | ||||
|     string _themetype; | ||||
|     string _layouttype; | ||||
|     string _containertype; | ||||
|     string _allowregistration; | ||||
|  | ||||
|     string _smtphost = ""; | ||||
|     string _smtpport = ""; | ||||
| @ -184,6 +243,12 @@ | ||||
|     string _smtpusername = ""; | ||||
|     string _smtppassword = ""; | ||||
|  | ||||
|     string _pwaisenabled; | ||||
|     int _pwaappiconfileid = -1; | ||||
|     FileManager _pwaappiconfilemanager; | ||||
|     int _pwasplashiconfileid = -1; | ||||
|     FileManager _pwasplashiconfilemanager; | ||||
|  | ||||
|     string _createdby; | ||||
|     DateTime _createdon; | ||||
|     string _modifiedby; | ||||
| @ -212,10 +277,15 @@ | ||||
|                 { | ||||
|                     _logofileid = site.LogoFileId.Value; | ||||
|                 } | ||||
|                 if (site.FaviconFileId != null) | ||||
|                 { | ||||
|                     _faviconfileid = site.FaviconFileId.Value; | ||||
|                 } | ||||
|                 _themetype = site.DefaultThemeType; | ||||
|                 _panelayouts = ThemeService.GetPaneLayoutTypes(_themeList, _themetype); | ||||
|                 _layouttype = site.DefaultLayoutType; | ||||
|                 _containertype = site.DefaultContainerType; | ||||
|                 _allowregistration = site.AllowRegistration.ToString(); | ||||
|  | ||||
|                 Dictionary<string, string> settings = await SettingService.GetSiteSettingsAsync(site.SiteId); | ||||
|                 _smtphost = SettingService.GetSetting(settings, "SMTPHost", ""); | ||||
| @ -224,6 +294,16 @@ | ||||
|                 _smtpusername = SettingService.GetSetting(settings, "SMTPUsername", ""); | ||||
|                 _smtppassword = SettingService.GetSetting(settings, "SMTPPassword", ""); | ||||
|  | ||||
|                 _pwaisenabled = site.PwaIsEnabled.ToString(); | ||||
|                 if (site.PwaAppIconFileId != null) | ||||
|                 { | ||||
|                     _pwaappiconfileid = site.PwaAppIconFileId.Value; | ||||
|                 } | ||||
|                 if (site.PwaSplashIconFileId != null) | ||||
|                 { | ||||
|                     _pwasplashiconfileid = site.PwaSplashIconFileId.Value; | ||||
|                 } | ||||
|  | ||||
|                 _createdby = site.CreatedBy; | ||||
|                 _createdon = site.CreatedOn; | ||||
|                 _modifiedby = site.ModifiedBy; | ||||
| @ -286,16 +366,34 @@ | ||||
|                     { | ||||
|                         site.Name = _name; | ||||
|                         site.LogoFileId = null; | ||||
|                         int logofileid = _filemanager.GetFileId(); | ||||
|                         int logofileid = _logofilemanager.GetFileId(); | ||||
|                         if (logofileid != -1) | ||||
|                         { | ||||
|                             site.LogoFileId = logofileid; | ||||
|                         } | ||||
|                         int faviconfileid = _faviconfilemanager.GetFileId(); | ||||
|                         if (faviconfileid != -1) | ||||
|                         { | ||||
|                             site.FaviconFileId = faviconfileid; | ||||
|                         } | ||||
|                         site.DefaultThemeType = _themetype; | ||||
|                         site.DefaultLayoutType = (_layouttype == null ? "" : _layouttype); | ||||
|                         site.DefaultContainerType = _containertype; | ||||
|                         site.AllowRegistration = (_allowregistration == null ? true : Boolean.Parse(_allowregistration)); | ||||
|                         site.IsDeleted = (_isdeleted == null ? true : Boolean.Parse(_isdeleted)); | ||||
|  | ||||
|                         site.PwaIsEnabled = (_pwaisenabled == null ? true : Boolean.Parse(_pwaisenabled)); | ||||
|                         int pwaappiconfileid = _pwaappiconfilemanager.GetFileId(); | ||||
|                         if (pwaappiconfileid != -1) | ||||
|                         { | ||||
|                             site.PwaAppIconFileId = pwaappiconfileid; | ||||
|                         } | ||||
|                         int pwasplashiconfileid = _pwasplashiconfilemanager.GetFileId(); | ||||
|                         if (pwasplashiconfileid != -1) | ||||
|                         { | ||||
|                             site.PwaSplashIconFileId = pwasplashiconfileid; | ||||
|                         } | ||||
|  | ||||
|                         site = await SiteService.UpdateSiteAsync(site, PageState.Alias); | ||||
|  | ||||
|                         _urls = _urls.Replace("\n", ","); | ||||
|  | ||||
| @ -248,9 +248,14 @@ else | ||||
|                     site.TenantId = int.Parse(_tenantid); | ||||
|                     site.Name = _name; | ||||
|                     site.LogoFileId = null; | ||||
|                     site.FaviconFileId = null; | ||||
|                     site.DefaultThemeType = _themetype; | ||||
|                     site.DefaultLayoutType = (_layouttype == null ? "" : _layouttype); | ||||
|                     site.DefaultContainerType = _containertype; | ||||
|                     site.PwaIsEnabled = false; | ||||
|                     site.PwaAppIconFileId = null; | ||||
|                     site.PwaSplashIconFileId = null; | ||||
|                     site.AllowRegistration = false; | ||||
|                     site.SiteTemplateType = _sitetemplatetype; | ||||
|                     site = await SiteService.AddSiteAsync(site, aliases[0]); | ||||
|  | ||||
|  | ||||
| @ -87,9 +87,7 @@ namespace Oqtane.Modules | ||||
|  | ||||
|         public string ContentUrl(int fileid) | ||||
|         { | ||||
|             string url = (PageState.Alias.Path == "") ? "/~" : PageState.Alias.Path; | ||||
|             url += Constants.ContentUrl + fileid.ToString(); | ||||
|             return url; | ||||
|             return Utilities.ContentUrl(PageState.Alias.Path, fileid); | ||||
|         } | ||||
|  | ||||
|         // user feedback methods | ||||
|  | ||||
| @ -41,7 +41,19 @@ | ||||
|                 securitylevel = int.MaxValue; | ||||
|  | ||||
|                 menu += "<li class=\"nav-item px-3\">"; | ||||
|                 menu += "<a href=\"" + NavigateUrl(p.Path) + "\" class=\"nav-link\" style=\"padding-left: " + ((p.Level + 1) * 15).ToString() + "px !important;\">"; | ||||
|                 if (string.IsNullOrEmpty(p.Url)) | ||||
|                 { | ||||
|                     menu += "<a href=\"" + NavigateUrl(p.Path) + "\" class=\"nav-link\" style=\"padding-left: " + ((p.Level + 1) * 15).ToString() + "px !important;\">"; | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     string target = ""; | ||||
|                     if (p.Url.StartsWith("http")) | ||||
|                     { | ||||
|                         target = " target=\"_new\""; | ||||
|                     } | ||||
|                     menu += "<a href=\"" + p.Url + "\" class=\"nav-link\" style=\"padding-left: " + ((p.Level + 1) * 15).ToString() + "px !important;\"" + target + ">"; | ||||
|                 } | ||||
|                 if (p.HasChildren) | ||||
|                 { | ||||
|                     menu += "<i class=\"oi oi-chevron-right\"></i>"; | ||||
| @ -69,6 +81,9 @@ | ||||
|  | ||||
|     private void CreateHorizontalMenu() | ||||
|     { | ||||
|         string url = ""; | ||||
|         string target = ""; | ||||
|  | ||||
|         menu = "<button class=\"navbar-toggler\" type=\"button\" data-toggle=\"collapse\" data-target=\"#Menu\" aria-controls=\"Menu\" aria-expanded=\"false\" aria-label=\"Toggle navigation\"><span class=\"navbar-toggler-icon\"></span></button>"; | ||||
|         menu += "<div class=\"collapse navbar-collapse\" id=\"Menu\">"; | ||||
|         menu += "<ul class=\"navbar-nav mr-auto\">"; | ||||
| @ -76,18 +91,32 @@ | ||||
|         { | ||||
|             if (UserSecurity.IsAuthorized(PageState.User,PermissionNames.View, p.Permissions) && p.ParentId == PageState.Page.ParentId && p.Level == PageState.Page.Level) | ||||
|             { | ||||
|                 if (string.IsNullOrEmpty(p.Url)) | ||||
|                 { | ||||
|                     url = NavigateUrl(p.Path); | ||||
|                     target = ""; | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     url = p.Url; | ||||
|                     if (p.Url.StartsWith("http")) | ||||
|                     { | ||||
|                         target = " target=\"_new\""; | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 if (p.PageId == PageState.Page.PageId) | ||||
|                 { | ||||
|                     menu += "<li class=\"nav-item active\">" + | ||||
|                         "<a class=\"nav-link\" href=\"" + NavigateUrl(p.Path) + "\">" + | ||||
|                         ((p.Icon != "") ? "<span class=\"oi oi-" + p.Icon + "\" aria-hidden=\"true\"></span> " : "") +  | ||||
|                         "<a class=\"nav-link\" href=\"" + url + "\"" + target + ">" + | ||||
|                         ((p.Icon != "") ? "<span class=\"oi oi-" + p.Icon + "\" aria-hidden=\"true\"></span> " : "") + | ||||
|                         p.Name + " <span class=\"sr-only\">(current)</span></a></li>"; | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     menu += "<li class=\"nav-item\">" + | ||||
|                         "<a class=\"nav-link\" href=\"" + NavigateUrl(p.Path) + "\">" + | ||||
|                         ((p.Icon != "") ? "<span class=\"oi oi-" + p.Icon + "\" aria-hidden=\"true\"></span> " : "") +  | ||||
|                         "<a class=\"nav-link\" href=\"" + url + "\"" + target + ">" + | ||||
|                         ((p.Icon != "") ? "<span class=\"oi oi-" + p.Icon + "\" aria-hidden=\"true\"></span> " : "") + | ||||
|                         p.Name + "</a></li>"; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
| @ -10,7 +10,10 @@ | ||||
|         <button type="button" class="btn btn-primary" @onclick="UpdateProfile">@context.User.Identity.Name</button> | ||||
|     </Authorized> | ||||
|     <NotAuthorized> | ||||
|         <button type="button" class="btn btn-primary" @onclick="RegisterUser">Register</button> | ||||
|         @if (PageState.Site.AllowRegistration) | ||||
|         { | ||||
|             <button type="button" class="btn btn-primary" @onclick="RegisterUser">Register</button> | ||||
|         } | ||||
|     </NotAuthorized> | ||||
| </AuthorizeView> | ||||
|  | ||||
|  | ||||
| @ -41,9 +41,7 @@ namespace Oqtane.Themes | ||||
|  | ||||
|         public string ContentUrl(int fileid) | ||||
|         { | ||||
|             string url = (PageState.Alias.Path == "") ? "/~" : PageState.Alias.Path; | ||||
|             url += Constants.ContentUrl + fileid.ToString(); | ||||
|             return url; | ||||
|             return Utilities.ContentUrl(PageState.Alias.Path, fileid); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -185,16 +185,21 @@ | ||||
|             }; | ||||
|  | ||||
|             Installation installation = await InstallationService.Install(config); | ||||
|     //TODO: Should be moved to Database manager | ||||
|             //TODO: Should be moved to Database manager | ||||
|             if (installation.Success) | ||||
|             { | ||||
|                 Site site = new Site(); | ||||
|                 site.TenantId = -1; // will be populated on server | ||||
|                 site.Name = "Default Site"; | ||||
|                 site.LogoFileId = null; | ||||
|                 site.FaviconFileId = null; | ||||
|                 site.DefaultThemeType = Constants.DefaultTheme; | ||||
|                 site.DefaultLayoutType = Constants.DefaultLayout; | ||||
|                 site.DefaultContainerType = Constants.DefaultContainer; | ||||
|                 site.PwaIsEnabled = false; | ||||
|                 site.PwaAppIconFileId = null; | ||||
|                 site.PwaSplashIconFileId = null; | ||||
|                 site.AllowRegistration = false; | ||||
|                 site = await SiteService.AddSiteAsync(site, null); | ||||
|  | ||||
|                 User user = new User(); | ||||
|  | ||||
| @ -58,12 +58,12 @@ namespace Oqtane.UI | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public Task UpdateMeta(string id, string attribute, string name, string content) | ||||
|         public Task IncludeMeta(string id, string attribute, string name, string content) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 _jsRuntime.InvokeAsync<string>( | ||||
|                     "interop.updateMeta", | ||||
|                     "interop.includeMeta", | ||||
|                     id, attribute, name, content); | ||||
|                 return Task.CompletedTask; | ||||
|             } | ||||
| @ -73,13 +73,28 @@ namespace Oqtane.UI | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public Task UpdateLink(string id, string rel, string type, string url) | ||||
|         public Task IncludeLink(string id, string rel, string url, string type) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 _jsRuntime.InvokeAsync<string>( | ||||
|                     "interop.updateLink", | ||||
|                     id, rel, type, url); | ||||
|                     "interop.includeLink", | ||||
|                     id, rel, url, type); | ||||
|                 return Task.CompletedTask; | ||||
|             } | ||||
|             catch | ||||
|             { | ||||
|                 return Task.CompletedTask; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public Task IncludeScript(string id, string src, string content, string location) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 _jsRuntime.InvokeAsync<string>( | ||||
|                     "interop.includeScript", | ||||
|                     id, src, content, location); | ||||
|                 return Task.CompletedTask; | ||||
|             } | ||||
|             catch | ||||
| @ -93,8 +108,8 @@ namespace Oqtane.UI | ||||
|             try | ||||
|             { | ||||
|                 _jsRuntime.InvokeAsync<string>( | ||||
|                     "interop.updateLink", | ||||
|                     id, "stylesheet", "text/css", url); | ||||
|                     "interop.includeLink", | ||||
|                     id, "stylesheet", url, "text/css"); | ||||
|                 return Task.CompletedTask; | ||||
|             } | ||||
|             catch | ||||
|  | ||||
| @ -1,5 +1,6 @@ | ||||
| @namespace Oqtane.UI | ||||
| @inject IJSRuntime JsRuntime | ||||
| @inject NavigationManager NavigationManager | ||||
|  | ||||
| @DynamicComponent | ||||
|  | ||||
| @ -8,8 +9,26 @@ | ||||
|  | ||||
|     RenderFragment DynamicComponent { get; set; } | ||||
|  | ||||
|     protected override void OnParametersSet() | ||||
|     protected override async Task OnParametersSetAsync() | ||||
|     { | ||||
|         var interop = new Interop(JsRuntime); | ||||
|         if (!string.IsNullOrEmpty(PageState.Page.Title)) | ||||
|         { | ||||
|             await interop.UpdateTitle(PageState.Page.Title); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             await interop.UpdateTitle(PageState.Site.Name + " - " + PageState.Page.Name); | ||||
|         } | ||||
|         if (PageState.Site.FaviconFileId != null) | ||||
|         { | ||||
|             await interop.IncludeLink("fav-icon", "shortcut icon", Utilities.ContentUrl(PageState.Alias.Path, PageState.Site.FaviconFileId.Value), "image/x-icon"); | ||||
|         } | ||||
|         if (PageState.Site.PwaIsEnabled) | ||||
|         { | ||||
|             await InitializePwa(interop); | ||||
|         } | ||||
|  | ||||
|         DynamicComponent = builder => | ||||
|         { | ||||
|             Type themeType = Type.GetType(PageState.Page.ThemeType); | ||||
| @ -27,4 +46,44 @@ | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     private async Task InitializePwa(Interop interop) | ||||
|     { | ||||
|         // dynamically create manifest.json and add to page | ||||
|         string manifest = "setTimeout(() => { " + | ||||
|             "var manifest = { " + | ||||
|             "\"name\": \"" + PageState.Site.Name + "\", " + | ||||
|             "\"short_name\": \"" + PageState.Site.Name + "\", " + | ||||
|             "\"start_url\": \"/\", " + | ||||
|             "\"display\": \"standalone\", " + | ||||
|             "\"background_color\": \"#fff\", " + | ||||
|             "\"description\": \"" + PageState.Site.Name + "\", " + | ||||
|             "\"icons\": [{ " + | ||||
|                 "\"src\": \"" + Utilities.ContentUrl(PageState.Alias.Path, PageState.Site.PwaAppIconFileId.Value) + "\", " + | ||||
|                 "\"sizes\": \"192x192\", " + | ||||
|                 "\"type\": \"image/png\" " + | ||||
|                 "}, { " + | ||||
|                 "\"src\": \"" + Utilities.ContentUrl(PageState.Alias.Path, PageState.Site.PwaSplashIconFileId.Value) + "\", " + | ||||
|                 "\"sizes\": \"512x512\", " + | ||||
|                 "\"type\": \"image/png\" " + | ||||
|             "}] " + | ||||
|             "} " + | ||||
|             "const serialized = JSON.stringify(manifest); " + | ||||
|             "const blob = new Blob([serialized], {type: 'application/javascript'}); " + | ||||
|             "const url = URL.createObjectURL(blob); " + | ||||
|             "document.getElementById('pwa-manifest').setAttribute('href', url); " + | ||||
|             "} " + | ||||
|             ", 1000);"; | ||||
|         await interop.IncludeScript("pwa-manifestscript", "", manifest, "body"); | ||||
|  | ||||
|         // service worker must be in root of site | ||||
|         string serviceworker = "if ('serviceWorker' in navigator) { " + | ||||
|             "navigator.serviceWorker.register('/service-worker.js').then(function(registration) { " + | ||||
|                 "console.log('ServiceWorker Registration Successful'); " + | ||||
|             "}).catch (function(err) { " + | ||||
|                 "console.log('ServiceWorker Registration Failed ', err); " + | ||||
|             "}); " + | ||||
|             "}"; | ||||
|         await interop.IncludeScript("pwa-serviceworker", "", serviceworker, "body"); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -5,6 +5,9 @@ | ||||
|     <meta name="viewport" content="width=device-width"> | ||||
|     <title>Oqtane</title> | ||||
|     <base href="/" /> | ||||
|     <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"> | ||||
|  | ||||
| @ -25,7 +25,7 @@ window.interop = { | ||||
|             document.title = title; | ||||
|         } | ||||
|     }, | ||||
|     updateMeta: function (id, attribute, name, content) { | ||||
|     includeMeta: function (id, attribute, name, content) { | ||||
|         var meta; | ||||
|         if (id !== "") { | ||||
|             meta = document.getElementById(id); | ||||
| @ -48,7 +48,7 @@ window.interop = { | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|     updateLink: function (id, rel, type, url) { | ||||
|     includeLink: function (id, rel, url, type) { | ||||
|         var link; | ||||
|         if (id !== "") { | ||||
|             link = document.getElementById(id); | ||||
| @ -62,14 +62,58 @@ window.interop = { | ||||
|                 link.id = id; | ||||
|             } | ||||
|             link.rel = rel; | ||||
|             link.type = type; | ||||
|             link.href = url; | ||||
|             if (type !== "") { | ||||
|                 link.type = type; | ||||
|             } | ||||
|             document.head.appendChild(link); | ||||
|         } | ||||
|         else { | ||||
|             if (link.rel !== rel) { | ||||
|                 link.setAttribute('rel', rel); | ||||
|             } | ||||
|             if (link.href !== url) { | ||||
|                 link.setAttribute('href', url); | ||||
|             } | ||||
|             if (type !== "" && link.type !== type) { | ||||
|                 link.setAttribute('type', type); | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|     includeScript: function (id, src, content, location) { | ||||
|         var script; | ||||
|         if (id !== "") { | ||||
|             script = document.getElementById(id); | ||||
|         } | ||||
|         if (script === null) { | ||||
|             script = document.createElement("script"); | ||||
|             if (id !== "") { | ||||
|                 script.id = id; | ||||
|             } | ||||
|             if (src !== "") { | ||||
|                 script.src = src; | ||||
|             } | ||||
|             else { | ||||
|                 script.innerHTML = content; | ||||
|             } | ||||
|             if (location === 'head') { | ||||
|                 document.head.appendChild(script); | ||||
|             } | ||||
|             if (location === 'body') { | ||||
|                 document.body.appendChild(script); | ||||
|             } | ||||
|         } | ||||
|         else { | ||||
|             if (src !== "") { | ||||
|                 if (script.src !== src) { | ||||
|                     script.src = src; | ||||
|                 } | ||||
|             } | ||||
|             else { | ||||
|                 if (script.innerHTML !== content) { | ||||
|                     script.innerHTML = content; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|     getElementByName: function (name) { | ||||
|  | ||||
							
								
								
									
										2
									
								
								Oqtane.Client/wwwroot/service-worker.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								Oqtane.Client/wwwroot/service-worker.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,2 @@ | ||||
| // always fetch from the network and do not enable offline support | ||||
| self.addEventListener('fetch', () => { }); | ||||
| @ -146,10 +146,12 @@ namespace Oqtane.Controllers | ||||
|                 page = new Page(); | ||||
|                 page.SiteId = parent.SiteId; | ||||
|                 page.Name = parent.Name; | ||||
|                 page.Title = parent.Title; | ||||
|                 page.Path = parent.Path; | ||||
|                 page.ParentId = parent.PageId; | ||||
|                 page.Order = 0; | ||||
|                 page.IsNavigation = false; | ||||
|                 page.Url = ""; | ||||
|                 page.EditMode = false; | ||||
|                 page.ThemeType = parent.ThemeType; | ||||
|                 page.LayoutType = parent.LayoutType; | ||||
|  | ||||
| @ -9,6 +9,9 @@ | ||||
|     <meta name="viewport" content="width=device-width"> | ||||
|     <title>Oqtane</title> | ||||
|     <base href="~/" /> | ||||
|     <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"> | ||||
|  | ||||
| @ -634,8 +634,10 @@ namespace Oqtane.Repository | ||||
|                     SiteId = site.SiteId, | ||||
|                     ParentId = parentid, | ||||
|                     Name = pagetemplate.Name, | ||||
|                     Title = "", | ||||
|                     Path = pagetemplate.Path, | ||||
|                     Order = 1, | ||||
|                     Url = "", | ||||
|                     IsNavigation = pagetemplate.IsNavigation, | ||||
|                     EditMode = pagetemplate.EditMode, | ||||
|                     ThemeType = "", | ||||
|  | ||||
| @ -9,9 +9,14 @@ CREATE TABLE [dbo].[Site]( | ||||
| 	[TenantId] [int] NOT NULL, | ||||
| 	[Name] [nvarchar](200) NOT NULL, | ||||
| 	[LogoFileId] [int] NULL, | ||||
| 	[FaviconFileId] [int] NULL, | ||||
| 	[DefaultThemeType] [nvarchar](200) NOT NULL, | ||||
| 	[DefaultLayoutType] [nvarchar](200) NOT NULL, | ||||
| 	[DefaultContainerType] [nvarchar](200) NOT NULL, | ||||
| 	[PwaIsEnabled] [bit] NOT NULL, | ||||
| 	[PwaAppIconFileId] [int] NULL, | ||||
| 	[PwaSplashIconFileId] [int] NULL, | ||||
| 	[AllowRegistration] [bit] NOT NULL, | ||||
| 	[CreatedBy] [nvarchar](256) NOT NULL, | ||||
| 	[CreatedOn] [datetime] NOT NULL, | ||||
| 	[ModifiedBy] [nvarchar](256) NOT NULL, | ||||
| @ -31,11 +36,13 @@ CREATE TABLE [dbo].[Page]( | ||||
| 	[SiteId] [int] NOT NULL, | ||||
| 	[Path] [nvarchar](50) NOT NULL, | ||||
| 	[Name] [nvarchar](50) NOT NULL, | ||||
| 	[Title] [nvarchar](200) NULL, | ||||
| 	[ThemeType] [nvarchar](200) NULL, | ||||
| 	[Icon] [nvarchar](50) NOT NULL, | ||||
| 	[ParentId] [int] NULL, | ||||
| 	[Order] [int] NOT NULL, | ||||
| 	[IsNavigation] [bit] NOT NULL, | ||||
| 	[Url] [nvarchar](500) NULL, | ||||
| 	[LayoutType] [nvarchar](200) NOT NULL, | ||||
| 	[EditMode] [bit] NOT NULL, | ||||
| 	[UserId] [int] NULL, | ||||
|  | ||||
| @ -25,7 +25,7 @@ window.interop = { | ||||
|             document.title = title; | ||||
|         } | ||||
|     }, | ||||
|     updateMeta: function (id, attribute, name, content) { | ||||
|     includeMeta: function (id, attribute, name, content) { | ||||
|         var meta; | ||||
|         if (id !== "") { | ||||
|             meta = document.getElementById(id); | ||||
| @ -48,7 +48,7 @@ window.interop = { | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|     updateLink: function (id, rel, type, url) { | ||||
|     includeLink: function (id, rel, url, type) { | ||||
|         var link; | ||||
|         if (id !== "") { | ||||
|             link = document.getElementById(id); | ||||
| @ -62,14 +62,58 @@ window.interop = { | ||||
|                 link.id = id; | ||||
|             } | ||||
|             link.rel = rel; | ||||
|             link.type = type; | ||||
|             link.href = url; | ||||
|             if (type !== "") { | ||||
|                 link.type = type; | ||||
|             } | ||||
|             document.head.appendChild(link); | ||||
|         } | ||||
|         else { | ||||
|             if (link.rel !== rel) { | ||||
|                 link.setAttribute('rel', rel); | ||||
|             } | ||||
|             if (link.href !== url) { | ||||
|                 link.setAttribute('href', url); | ||||
|             } | ||||
|             if (type !== "" && link.type !== type) { | ||||
|                 link.setAttribute('type', type); | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|     includeScript: function (id, src, content, location) { | ||||
|         var script; | ||||
|         if (id !== "") { | ||||
|             script = document.getElementById(id); | ||||
|         } | ||||
|         if (script === null) { | ||||
|             script = document.createElement("script"); | ||||
|             if (id !== "") { | ||||
|                 script.id = id; | ||||
|             } | ||||
|             if (src !== "") { | ||||
|                 script.src = src; | ||||
|             } | ||||
|             else { | ||||
|                 script.innerHTML = content; | ||||
|             } | ||||
|             if (location === 'head') { | ||||
|                 document.head.appendChild(script); | ||||
|             } | ||||
|             if (location === 'body') { | ||||
|                 document.body.appendChild(script); | ||||
|             } | ||||
|         } | ||||
|         else { | ||||
|             if (src !== "") { | ||||
|                 if (script.src !== src) { | ||||
|                     script.src = src; | ||||
|                 } | ||||
|             } | ||||
|             else { | ||||
|                 if (script.innerHTML !== content) { | ||||
|                     script.innerHTML = content; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|     getElementByName: function (name) { | ||||
|  | ||||
							
								
								
									
										2
									
								
								Oqtane.Server/wwwroot/service-worker.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								Oqtane.Server/wwwroot/service-worker.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,2 @@ | ||||
| // always fetch from the network and do not enable offline support | ||||
| self.addEventListener('fetch', () => { }); | ||||
| @ -9,8 +9,10 @@ namespace Oqtane.Models | ||||
|         public int SiteId { get; set; } | ||||
|         public int? ParentId { get; set; } | ||||
|         public string Name { get; set; } | ||||
|         public string Title { get; set; } | ||||
|         public string Path { get; set; } | ||||
|         public int Order { get; set; } | ||||
|         public string Url { get; set; } | ||||
|         public string ThemeType { get; set; } | ||||
|         public string LayoutType { get; set; } | ||||
|         public string Icon { get; set; } | ||||
|  | ||||
| @ -9,9 +9,14 @@ namespace Oqtane.Models | ||||
|         public int TenantId { get; set; } | ||||
|         public string Name { get; set; } | ||||
|         public int? LogoFileId { get; set; } | ||||
|         public int? FaviconFileId { get; set; } | ||||
|         public string DefaultThemeType { get; set; } | ||||
|         public string DefaultLayoutType { get; set; } | ||||
|         public string DefaultContainerType { get; set; } | ||||
|         public bool PwaIsEnabled { get; set; } | ||||
|         public int? PwaAppIconFileId { get; set; } | ||||
|         public int? PwaSplashIconFileId { get; set; } | ||||
|         public bool AllowRegistration { get; set; } | ||||
|  | ||||
|         public string CreatedBy { get; set; } | ||||
|         public DateTime CreatedOn { get; set; } | ||||
|  | ||||
| @ -56,6 +56,13 @@ namespace Oqtane.Shared | ||||
|             return url; | ||||
|         } | ||||
|  | ||||
|         public static string ContentUrl(string alias, int fileid) | ||||
|         { | ||||
|             string url = (alias == "") ? "/~" : alias; | ||||
|             url += Constants.ContentUrl + fileid.ToString(); | ||||
|             return url; | ||||
|         } | ||||
|  | ||||
|         public static string GetTypeName(string fullyqualifiedtypename) | ||||
|         { | ||||
|             if (fullyqualifiedtypename.Contains(",")) | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Shaun Walker
					Shaun Walker