| @@ -1,986 +0,0 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <!-- | |||
| IIS configuration sections. | |||
| For schema documentation, see | |||
| %IIS_BIN%\config\schema\IIS_schema.xml. | |||
| Please make a backup of this file before making any changes to it. | |||
| NOTE: The following environment variables are available to be used | |||
| within this file and are understood by the IIS Express. | |||
| %IIS_USER_HOME% - The IIS Express home directory for the user | |||
| %IIS_SITES_HOME% - The default home directory for sites | |||
| %IIS_BIN% - The location of the IIS Express binaries | |||
| %SYSTEMDRIVE% - The drive letter of %IIS_BIN% | |||
| --> | |||
| <configuration> | |||
| <!-- | |||
| The <configSections> section controls the registration of sections. | |||
| Section is the basic unit of deployment, locking, searching and | |||
| containment for configuration settings. | |||
| Every section belongs to one section group. | |||
| A section group is a container of logically-related sections. | |||
| Sections cannot be nested. | |||
| Section groups may be nested. | |||
| <section | |||
| name="" [Required, Collection Key] [XML name of the section] | |||
| allowDefinition="Everywhere" [MachineOnly|MachineToApplication|AppHostOnly|Everywhere] [Level where it can be set] | |||
| overrideModeDefault="Allow" [Allow|Deny] [Default delegation mode] | |||
| allowLocation="true" [true|false] [Allowed in location tags] | |||
| /> | |||
| The recommended way to unlock sections is by using a location tag: | |||
| <location path="Default Web Site" overrideMode="Allow"> | |||
| <system.webServer> | |||
| <asp /> | |||
| </system.webServer> | |||
| </location> | |||
| --> | |||
| <configSections> | |||
| <sectionGroup name="system.applicationHost"> | |||
| <section name="applicationPools" allowDefinition="AppHostOnly" overrideModeDefault="Deny" /> | |||
| <section name="configHistory" allowDefinition="AppHostOnly" overrideModeDefault="Deny" /> | |||
| <section name="customMetadata" allowDefinition="AppHostOnly" overrideModeDefault="Deny" /> | |||
| <section name="listenerAdapters" allowDefinition="AppHostOnly" overrideModeDefault="Deny" /> | |||
| <section name="log" allowDefinition="AppHostOnly" overrideModeDefault="Deny" /> | |||
| <section name="serviceAutoStartProviders" allowDefinition="AppHostOnly" overrideModeDefault="Deny" /> | |||
| <section name="sites" allowDefinition="AppHostOnly" overrideModeDefault="Deny" /> | |||
| <section name="webLimits" allowDefinition="AppHostOnly" overrideModeDefault="Deny" /> | |||
| </sectionGroup> | |||
| <sectionGroup name="system.webServer"> | |||
| <section name="asp" overrideModeDefault="Deny" /> | |||
| <section name="caching" overrideModeDefault="Allow" /> | |||
| <section name="cgi" overrideModeDefault="Deny" /> | |||
| <section name="defaultDocument" overrideModeDefault="Allow" /> | |||
| <section name="directoryBrowse" overrideModeDefault="Allow" /> | |||
| <section name="fastCgi" allowDefinition="AppHostOnly" overrideModeDefault="Deny" /> | |||
| <section name="globalModules" allowDefinition="AppHostOnly" overrideModeDefault="Deny" /> | |||
| <section name="handlers" overrideModeDefault="Deny" /> | |||
| <section name="httpCompression" overrideModeDefault="Allow" allowDefinition="Everywhere" /> | |||
| <section name="httpErrors" overrideModeDefault="Allow" /> | |||
| <section name="httpLogging" overrideModeDefault="Deny" /> | |||
| <section name="httpProtocol" overrideModeDefault="Allow" /> | |||
| <section name="httpRedirect" overrideModeDefault="Allow" /> | |||
| <section name="httpTracing" overrideModeDefault="Deny" /> | |||
| <section name="isapiFilters" allowDefinition="MachineToApplication" overrideModeDefault="Deny" /> | |||
| <section name="modules" allowDefinition="MachineToApplication" overrideModeDefault="Deny" /> | |||
| <section name="applicationInitialization" allowDefinition="MachineToApplication" overrideModeDefault="Allow" /> | |||
| <section name="odbcLogging" overrideModeDefault="Deny" /> | |||
| <sectionGroup name="security"> | |||
| <section name="access" overrideModeDefault="Deny" /> | |||
| <section name="applicationDependencies" overrideModeDefault="Deny" /> | |||
| <sectionGroup name="authentication"> | |||
| <section name="anonymousAuthentication" overrideModeDefault="Deny" /> | |||
| <section name="basicAuthentication" overrideModeDefault="Deny" /> | |||
| <section name="clientCertificateMappingAuthentication" overrideModeDefault="Deny" /> | |||
| <section name="digestAuthentication" overrideModeDefault="Deny" /> | |||
| <section name="iisClientCertificateMappingAuthentication" overrideModeDefault="Deny" /> | |||
| <section name="windowsAuthentication" overrideModeDefault="Deny" /> | |||
| </sectionGroup> | |||
| <section name="authorization" overrideModeDefault="Allow" /> | |||
| <section name="ipSecurity" overrideModeDefault="Deny" /> | |||
| <section name="dynamicIpSecurity" overrideModeDefault="Deny" /> | |||
| <section name="isapiCgiRestriction" allowDefinition="AppHostOnly" overrideModeDefault="Deny" /> | |||
| <section name="requestFiltering" overrideModeDefault="Allow" /> | |||
| </sectionGroup> | |||
| <section name="serverRuntime" overrideModeDefault="Deny" /> | |||
| <section name="serverSideInclude" overrideModeDefault="Deny" /> | |||
| <section name="staticContent" overrideModeDefault="Allow" /> | |||
| <sectionGroup name="tracing"> | |||
| <section name="traceFailedRequests" overrideModeDefault="Allow" /> | |||
| <section name="traceProviderDefinitions" overrideModeDefault="Deny" /> | |||
| </sectionGroup> | |||
| <section name="urlCompression" overrideModeDefault="Allow" /> | |||
| <section name="validation" overrideModeDefault="Allow" /> | |||
| <sectionGroup name="webdav"> | |||
| <section name="globalSettings" overrideModeDefault="Deny" /> | |||
| <section name="authoring" overrideModeDefault="Deny" /> | |||
| <section name="authoringRules" overrideModeDefault="Deny" /> | |||
| </sectionGroup> | |||
| <sectionGroup name="rewrite"> | |||
| <section name="allowedServerVariables" overrideModeDefault="Deny" /> | |||
| <section name="rules" overrideModeDefault="Allow" /> | |||
| <section name="outboundRules" overrideModeDefault="Allow" /> | |||
| <section name="globalRules" overrideModeDefault="Deny" allowDefinition="AppHostOnly" /> | |||
| <section name="providers" overrideModeDefault="Allow" /> | |||
| <section name="rewriteMaps" overrideModeDefault="Allow" /> | |||
| </sectionGroup> | |||
| <section name="webSocket" overrideModeDefault="Deny" /> | |||
| <section name="aspNetCore" overrideModeDefault="Allow" /> | |||
| </sectionGroup> | |||
| </configSections> | |||
| <configProtectedData> | |||
| <providers> | |||
| <add name="IISWASOnlyRsaProvider" type="" description="Uses RsaCryptoServiceProvider to encrypt and decrypt" keyContainerName="iisWasKey" cspProviderName="" useMachineContainer="true" useOAEP="false" /> | |||
| <add name="AesProvider" type="Microsoft.ApplicationHost.AesProtectedConfigurationProvider" description="Uses an AES session key to encrypt and decrypt" keyContainerName="iisConfigurationKey" cspProviderName="" useOAEP="false" useMachineContainer="true" sessionKey="AQIAAA5mAAAApAAA/HKxkz6alrlAPez0IUgujj/6k3WxCDriHp6jvpv3yEZmo7h6SMzGLxo4mTrIQVHSkB7tmElHKfUFTzE2BWF7nFWHY6Z6qmGBauFzwJMwESjril7Gjz69RBFH259HQ6aRDq9Xfx7U7H4HtdmnKNqGjgl/hwPQBGeIlWiDh+sYv3vKB0QU971tjX6H2B+9armlnC8UOuA6JYMDMI/VLLL16sng0fWAy5JYe0YVABVjiAWDW264RZW9Tr1Oax4qHZKg+SdjULxeOc2YmpX+d0yeITo1HkPF1hN1gHpIPIUDo05ilHUNfR3OkjVCIQK4cFKCq1s8NH+y+13MxUC4Fn1AlQ==" /> | |||
| <add name="IISWASOnlyAesProvider" type="Microsoft.ApplicationHost.AesProtectedConfigurationProvider" description="Uses an AES session key to encrypt and decrypt" keyContainerName="iisWasKey" cspProviderName="" useOAEP="false" useMachineContainer="true" sessionKey="AQIAAA5mAAAApAAALmU8lTC+v2qtfQiiiquvvLpUQqKLEXs+jSKoWCM/uPhyB++k4dwug19mGidNK5FYiWK2KYE1yhjVJcbp12E98Q0R2nT7eBiCMY2JairxQ591rqABK7keGaIjwH7PwGzSpILl3RJ4YFvJ/7ZXEJxeDZIjW8ZxWVXx+/VyHs9U3WguLEkgMUX3jrxJi8LouxaIVPJAv/YQ1ZCWs8zImitxX/C/7o7yaIxznfsN5nGQzQfpUDPeby99aw2zPVTtZI2LaWIBON8guABvZ6JtJVDWmfdK6sodbnwdZkr6/Z2rfvamT1dC1SpQrGG7ulR/f9/GXvCaW10ZVKxekBF/CYlNMg==" /> | |||
| </providers> | |||
| </configProtectedData> | |||
| <system.applicationHost> | |||
| <applicationPools> | |||
| <add name="Clr4IntegratedAppPool" managedRuntimeVersion="v4.0" managedPipelineMode="Integrated" CLRConfigFile="%IIS_USER_HOME%\config\aspnet.config" autoStart="true" /> | |||
| <add name="Clr4ClassicAppPool" managedRuntimeVersion="v4.0" managedPipelineMode="Classic" CLRConfigFile="%IIS_USER_HOME%\config\aspnet.config" autoStart="true" /> | |||
| <add name="Clr2IntegratedAppPool" managedRuntimeVersion="v2.0" managedPipelineMode="Integrated" CLRConfigFile="%IIS_USER_HOME%\config\aspnet.config" autoStart="true" /> | |||
| <add name="Clr2ClassicAppPool" managedRuntimeVersion="v2.0" managedPipelineMode="Classic" CLRConfigFile="%IIS_USER_HOME%\config\aspnet.config" autoStart="true" /> | |||
| <add name="UnmanagedClassicAppPool" managedRuntimeVersion="" managedPipelineMode="Classic" autoStart="true" /> | |||
| <add name="MVCTemplate AppPool" managedRuntimeVersion="" /> | |||
| <applicationPoolDefaults managedRuntimeVersion="v4.0"> | |||
| <processModel loadUserProfile="true" setProfileEnvironment="false" /> | |||
| </applicationPoolDefaults> | |||
| </applicationPools> | |||
| <!-- | |||
| The <listenerAdapters> section defines the protocols with which the | |||
| Windows Process Activation Service (WAS) binds. | |||
| --> | |||
| <listenerAdapters> | |||
| <add name="http" /> | |||
| </listenerAdapters> | |||
| <sites> | |||
| <site name="WebSite1" id="1" serverAutoStart="true"> | |||
| <application path="/"> | |||
| <virtualDirectory path="/" physicalPath="%IIS_SITES_HOME%\WebSite1" /> | |||
| </application> | |||
| <bindings> | |||
| <binding protocol="http" bindingInformation=":8080:localhost" /> | |||
| </bindings> | |||
| </site> | |||
| <site name="MVCTemplate" id="2"> | |||
| <application path="/" applicationPool="MVCTemplate AppPool"> | |||
| <virtualDirectory path="/" physicalPath="C:\Users\julija.stojkovic\source\repos\secure-sharing\MVCTemplate" /> | |||
| </application> | |||
| <bindings> | |||
| <binding protocol="http" bindingInformation="*:24744:localhost" /> | |||
| <binding protocol="https" bindingInformation="*:44336:localhost" /> | |||
| </bindings> | |||
| </site> | |||
| <siteDefaults> | |||
| <!-- To enable logging, please change the below attribute "enabled" to "true" --> | |||
| <logFile logFormat="W3C" directory="%AppData%\Microsoft\IISExpressLogs" enabled="false" /> | |||
| <traceFailedRequestsLogging directory="%AppData%\Microsoft" enabled="false" maxLogFileSizeKB="1024" /> | |||
| </siteDefaults> | |||
| <applicationDefaults applicationPool="Clr4IntegratedAppPool" /> | |||
| <virtualDirectoryDefaults allowSubDirConfig="true" /> | |||
| </sites> | |||
| <webLimits /> | |||
| </system.applicationHost> | |||
| <system.webServer> | |||
| <serverRuntime /> | |||
| <asp scriptErrorSentToBrowser="true"> | |||
| <cache diskTemplateCacheDirectory="%TEMP%\iisexpress\ASP Compiled Templates" /> | |||
| <limits /> | |||
| </asp> | |||
| <caching enabled="true" enableKernelCache="true"></caching> | |||
| <cgi /> | |||
| <defaultDocument enabled="true"> | |||
| <files> | |||
| <add value="Default.htm" /> | |||
| <add value="Default.asp" /> | |||
| <add value="index.htm" /> | |||
| <add value="index.html" /> | |||
| <add value="iisstart.htm" /> | |||
| <add value="default.aspx" /> | |||
| </files> | |||
| </defaultDocument> | |||
| <directoryBrowse enabled="false" /> | |||
| <fastCgi /> | |||
| <!-- | |||
| The <globalModules> section defines all native-code modules. | |||
| To enable a module, specify it in the <modules> section. | |||
| --> | |||
| <globalModules> | |||
| <add name="HttpLoggingModule" image="%IIS_BIN%\loghttp.dll" /> | |||
| <add name="UriCacheModule" image="%IIS_BIN%\cachuri.dll" /> | |||
| <add name="TokenCacheModule" image="%IIS_BIN%\cachtokn.dll" /> | |||
| <add name="DynamicCompressionModule" image="%IIS_BIN%\compdyn.dll" /> | |||
| <add name="StaticCompressionModule" image="%IIS_BIN%\compstat.dll" /> | |||
| <add name="DefaultDocumentModule" image="%IIS_BIN%\defdoc.dll" /> | |||
| <add name="DirectoryListingModule" image="%IIS_BIN%\dirlist.dll" /> | |||
| <add name="ProtocolSupportModule" image="%IIS_BIN%\protsup.dll" /> | |||
| <add name="HttpRedirectionModule" image="%IIS_BIN%\redirect.dll" /> | |||
| <add name="ServerSideIncludeModule" image="%IIS_BIN%\iis_ssi.dll" /> | |||
| <add name="StaticFileModule" image="%IIS_BIN%\static.dll" /> | |||
| <add name="AnonymousAuthenticationModule" image="%IIS_BIN%\authanon.dll" /> | |||
| <add name="CertificateMappingAuthenticationModule" image="%IIS_BIN%\authcert.dll" /> | |||
| <add name="UrlAuthorizationModule" image="%IIS_BIN%\urlauthz.dll" /> | |||
| <add name="BasicAuthenticationModule" image="%IIS_BIN%\authbas.dll" /> | |||
| <add name="WindowsAuthenticationModule" image="%IIS_BIN%\authsspi.dll" /> | |||
| <add name="IISCertificateMappingAuthenticationModule" image="%IIS_BIN%\authmap.dll" /> | |||
| <add name="IpRestrictionModule" image="%IIS_BIN%\iprestr.dll" /> | |||
| <add name="DynamicIpRestrictionModule" image="%IIS_BIN%\diprestr.dll" /> | |||
| <add name="RequestFilteringModule" image="%IIS_BIN%\modrqflt.dll" /> | |||
| <add name="CustomLoggingModule" image="%IIS_BIN%\logcust.dll" /> | |||
| <add name="CustomErrorModule" image="%IIS_BIN%\custerr.dll" /> | |||
| <add name="FailedRequestsTracingModule" image="%IIS_BIN%\iisfreb.dll" /> | |||
| <add name="RequestMonitorModule" image="%IIS_BIN%\iisreqs.dll" /> | |||
| <add name="IsapiModule" image="%IIS_BIN%\isapi.dll" /> | |||
| <add name="IsapiFilterModule" image="%IIS_BIN%\filter.dll" /> | |||
| <add name="CgiModule" image="%IIS_BIN%\cgi.dll" /> | |||
| <add name="FastCgiModule" image="%IIS_BIN%\iisfcgi.dll" /> | |||
| <!-- <add name="WebDAVModule" image="%IIS_BIN%\webdav.dll" /> --> | |||
| <add name="RewriteModule" image="%IIS_BIN%\rewrite.dll" /> | |||
| <add name="ConfigurationValidationModule" image="%IIS_BIN%\validcfg.dll" /> | |||
| <add name="WebSocketModule" image="%IIS_BIN%\iiswsock.dll" /> | |||
| <add name="WebMatrixSupportModule" image="%IIS_BIN%\webmatrixsup.dll" /> | |||
| <add name="ManagedEngine" image="%windir%\Microsoft.NET\Framework\v2.0.50727\webengine.dll" preCondition="integratedMode,runtimeVersionv2.0,bitness32" /> | |||
| <add name="ManagedEngine64" image="%windir%\Microsoft.NET\Framework64\v2.0.50727\webengine.dll" preCondition="integratedMode,runtimeVersionv2.0,bitness64" /> | |||
| <add name="ManagedEngineV4.0_32bit" image="%windir%\Microsoft.NET\Framework\v4.0.30319\webengine4.dll" preCondition="integratedMode,runtimeVersionv4.0,bitness32" /> | |||
| <add name="ManagedEngineV4.0_64bit" image="%windir%\Microsoft.NET\Framework64\v4.0.30319\webengine4.dll" preCondition="integratedMode,runtimeVersionv4.0,bitness64" /> | |||
| <add name="ApplicationInitializationModule" image="%IIS_BIN%\warmup.dll" /> | |||
| <add name="AspNetCoreModuleV2" image="%IIS_BIN%\Asp.Net Core Module\V2\aspnetcorev2.dll" /> | |||
| </globalModules> | |||
| <httpCompression directory="%TEMP%"> | |||
| <scheme name="gzip" dll="%IIS_BIN%\gzip.dll" /> | |||
| <dynamicTypes> | |||
| <add mimeType="text/*" enabled="true" /> | |||
| <add mimeType="message/*" enabled="true" /> | |||
| <add mimeType="application/x-javascript" enabled="true" /> | |||
| <add mimeType="application/javascript" enabled="true" /> | |||
| <add mimeType="*/*" enabled="false" /> | |||
| </dynamicTypes> | |||
| <staticTypes> | |||
| <add mimeType="text/*" enabled="true" /> | |||
| <add mimeType="message/*" enabled="true" /> | |||
| <add mimeType="application/javascript" enabled="true" /> | |||
| <add mimeType="application/atom+xml" enabled="true" /> | |||
| <add mimeType="application/xaml+xml" enabled="true" /> | |||
| <add mimeType="image/svg+xml" enabled="true" /> | |||
| <add mimeType="*/*" enabled="false" /> | |||
| </staticTypes> | |||
| </httpCompression> | |||
| <httpErrors lockAttributes="allowAbsolutePathsWhenDelegated,defaultPath"> | |||
| <error statusCode="401" prefixLanguageFilePath="%IIS_BIN%\custerr" path="401.htm" /> | |||
| <error statusCode="403" prefixLanguageFilePath="%IIS_BIN%\custerr" path="403.htm" /> | |||
| <error statusCode="404" prefixLanguageFilePath="%IIS_BIN%\custerr" path="404.htm" /> | |||
| <error statusCode="405" prefixLanguageFilePath="%IIS_BIN%\custerr" path="405.htm" /> | |||
| <error statusCode="406" prefixLanguageFilePath="%IIS_BIN%\custerr" path="406.htm" /> | |||
| <error statusCode="412" prefixLanguageFilePath="%IIS_BIN%\custerr" path="412.htm" /> | |||
| <error statusCode="500" prefixLanguageFilePath="%IIS_BIN%\custerr" path="500.htm" /> | |||
| <error statusCode="501" prefixLanguageFilePath="%IIS_BIN%\custerr" path="501.htm" /> | |||
| <error statusCode="502" prefixLanguageFilePath="%IIS_BIN%\custerr" path="502.htm" /> | |||
| </httpErrors> | |||
| <httpLogging dontLog="false" /> | |||
| <httpProtocol> | |||
| <customHeaders> | |||
| <clear /> | |||
| <add name="X-Powered-By" value="ASP.NET" /> | |||
| </customHeaders> | |||
| <redirectHeaders> | |||
| <clear /> | |||
| </redirectHeaders> | |||
| </httpProtocol> | |||
| <httpRedirect enabled="false" /> | |||
| <httpTracing /> | |||
| <isapiFilters> | |||
| <filter name="ASP.Net_2.0.50727-64" path="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_filter.dll" enableCache="true" preCondition="bitness64,runtimeVersionv2.0" /> | |||
| <filter name="ASP.Net_2.0.50727.0" path="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_filter.dll" enableCache="true" preCondition="bitness32,runtimeVersionv2.0" /> | |||
| <filter name="ASP.Net_2.0_for_v1.1" path="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_filter.dll" enableCache="true" preCondition="runtimeVersionv1.1" /> | |||
| <filter name="ASP.Net_4.0_32bit" path="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_filter.dll" enableCache="true" preCondition="bitness32,runtimeVersionv4.0" /> | |||
| <filter name="ASP.Net_4.0_64bit" path="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_filter.dll" enableCache="true" preCondition="bitness64,runtimeVersionv4.0" /> | |||
| </isapiFilters> | |||
| <odbcLogging /> | |||
| <security> | |||
| <access sslFlags="None" /> | |||
| <applicationDependencies> | |||
| <application name="Active Server Pages" groupId="ASP" /> | |||
| </applicationDependencies> | |||
| <authentication> | |||
| <anonymousAuthentication enabled="true" userName="" /> | |||
| <basicAuthentication enabled="false" /> | |||
| <clientCertificateMappingAuthentication enabled="false" /> | |||
| <digestAuthentication enabled="false" /> | |||
| <iisClientCertificateMappingAuthentication enabled="false"></iisClientCertificateMappingAuthentication> | |||
| <windowsAuthentication enabled="false"> | |||
| <providers> | |||
| <add value="Negotiate" /> | |||
| <add value="NTLM" /> | |||
| </providers> | |||
| </windowsAuthentication> | |||
| </authentication> | |||
| <authorization> | |||
| <add accessType="Allow" users="*" /> | |||
| </authorization> | |||
| <ipSecurity allowUnlisted="true" /> | |||
| <isapiCgiRestriction notListedIsapisAllowed="true" notListedCgisAllowed="true"> | |||
| <add path="%windir%\Microsoft.NET\Framework64\v4.0.30319\webengine4.dll" allowed="true" groupId="ASP.NET_v4.0" description="ASP.NET_v4.0" /> | |||
| <add path="%windir%\Microsoft.NET\Framework\v4.0.30319\webengine4.dll" allowed="true" groupId="ASP.NET_v4.0" description="ASP.NET_v4.0" /> | |||
| <add path="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" allowed="true" groupId="ASP.NET v2.0.50727" description="ASP.NET v2.0.50727" /> | |||
| <add path="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" allowed="true" groupId="ASP.NET v2.0.50727" description="ASP.NET v2.0.50727" /> | |||
| </isapiCgiRestriction> | |||
| <requestFiltering> | |||
| <fileExtensions allowUnlisted="true" applyToWebDAV="true"> | |||
| <add fileExtension=".asa" allowed="false" /> | |||
| <add fileExtension=".asax" allowed="false" /> | |||
| <add fileExtension=".ascx" allowed="false" /> | |||
| <add fileExtension=".master" allowed="false" /> | |||
| <add fileExtension=".skin" allowed="false" /> | |||
| <add fileExtension=".browser" allowed="false" /> | |||
| <add fileExtension=".sitemap" allowed="false" /> | |||
| <add fileExtension=".config" allowed="false" /> | |||
| <add fileExtension=".cs" allowed="false" /> | |||
| <add fileExtension=".csproj" allowed="false" /> | |||
| <add fileExtension=".vb" allowed="false" /> | |||
| <add fileExtension=".vbproj" allowed="false" /> | |||
| <add fileExtension=".webinfo" allowed="false" /> | |||
| <add fileExtension=".licx" allowed="false" /> | |||
| <add fileExtension=".resx" allowed="false" /> | |||
| <add fileExtension=".resources" allowed="false" /> | |||
| <add fileExtension=".mdb" allowed="false" /> | |||
| <add fileExtension=".vjsproj" allowed="false" /> | |||
| <add fileExtension=".java" allowed="false" /> | |||
| <add fileExtension=".jsl" allowed="false" /> | |||
| <add fileExtension=".ldb" allowed="false" /> | |||
| <add fileExtension=".dsdgm" allowed="false" /> | |||
| <add fileExtension=".ssdgm" allowed="false" /> | |||
| <add fileExtension=".lsad" allowed="false" /> | |||
| <add fileExtension=".ssmap" allowed="false" /> | |||
| <add fileExtension=".cd" allowed="false" /> | |||
| <add fileExtension=".dsprototype" allowed="false" /> | |||
| <add fileExtension=".lsaprototype" allowed="false" /> | |||
| <add fileExtension=".sdm" allowed="false" /> | |||
| <add fileExtension=".sdmDocument" allowed="false" /> | |||
| <add fileExtension=".mdf" allowed="false" /> | |||
| <add fileExtension=".ldf" allowed="false" /> | |||
| <add fileExtension=".ad" allowed="false" /> | |||
| <add fileExtension=".dd" allowed="false" /> | |||
| <add fileExtension=".ldd" allowed="false" /> | |||
| <add fileExtension=".sd" allowed="false" /> | |||
| <add fileExtension=".adprototype" allowed="false" /> | |||
| <add fileExtension=".lddprototype" allowed="false" /> | |||
| <add fileExtension=".exclude" allowed="false" /> | |||
| <add fileExtension=".refresh" allowed="false" /> | |||
| <add fileExtension=".compiled" allowed="false" /> | |||
| <add fileExtension=".msgx" allowed="false" /> | |||
| <add fileExtension=".vsdisco" allowed="false" /> | |||
| <add fileExtension=".rules" allowed="false" /> | |||
| </fileExtensions> | |||
| <verbs allowUnlisted="true" applyToWebDAV="true" /> | |||
| <hiddenSegments applyToWebDAV="true"> | |||
| <add segment="web.config" /> | |||
| <add segment="bin" /> | |||
| <add segment="App_code" /> | |||
| <add segment="App_GlobalResources" /> | |||
| <add segment="App_LocalResources" /> | |||
| <add segment="App_WebReferences" /> | |||
| <add segment="App_Data" /> | |||
| <add segment="App_Browsers" /> | |||
| </hiddenSegments> | |||
| </requestFiltering> | |||
| </security> | |||
| <serverSideInclude ssiExecDisable="false" /> | |||
| <staticContent lockAttributes="isDocFooterFileName"> | |||
| <mimeMap fileExtension=".323" mimeType="text/h323" /> | |||
| <mimeMap fileExtension=".3g2" mimeType="video/3gpp2" /> | |||
| <mimeMap fileExtension=".3gp2" mimeType="video/3gpp2" /> | |||
| <mimeMap fileExtension=".3gp" mimeType="video/3gpp" /> | |||
| <mimeMap fileExtension=".3gpp" mimeType="video/3gpp" /> | |||
| <mimeMap fileExtension=".aac" mimeType="audio/aac" /> | |||
| <mimeMap fileExtension=".aaf" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".aca" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".accdb" mimeType="application/msaccess" /> | |||
| <mimeMap fileExtension=".accde" mimeType="application/msaccess" /> | |||
| <mimeMap fileExtension=".accdt" mimeType="application/msaccess" /> | |||
| <mimeMap fileExtension=".acx" mimeType="application/internet-property-stream" /> | |||
| <mimeMap fileExtension=".adt" mimeType="audio/vnd.dlna.adts" /> | |||
| <mimeMap fileExtension=".adts" mimeType="audio/vnd.dlna.adts" /> | |||
| <mimeMap fileExtension=".afm" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".ai" mimeType="application/postscript" /> | |||
| <mimeMap fileExtension=".aif" mimeType="audio/x-aiff" /> | |||
| <mimeMap fileExtension=".aifc" mimeType="audio/aiff" /> | |||
| <mimeMap fileExtension=".aiff" mimeType="audio/aiff" /> | |||
| <mimeMap fileExtension=".appcache" mimeType="text/cache-manifest" /> | |||
| <mimeMap fileExtension=".application" mimeType="application/x-ms-application" /> | |||
| <mimeMap fileExtension=".art" mimeType="image/x-jg" /> | |||
| <mimeMap fileExtension=".asd" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".asf" mimeType="video/x-ms-asf" /> | |||
| <mimeMap fileExtension=".asi" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".asm" mimeType="text/plain" /> | |||
| <mimeMap fileExtension=".asr" mimeType="video/x-ms-asf" /> | |||
| <mimeMap fileExtension=".asx" mimeType="video/x-ms-asf" /> | |||
| <mimeMap fileExtension=".atom" mimeType="application/atom+xml" /> | |||
| <mimeMap fileExtension=".au" mimeType="audio/basic" /> | |||
| <mimeMap fileExtension=".avi" mimeType="video/avi" /> | |||
| <mimeMap fileExtension=".axs" mimeType="application/olescript" /> | |||
| <mimeMap fileExtension=".bas" mimeType="text/plain" /> | |||
| <mimeMap fileExtension=".bcpio" mimeType="application/x-bcpio" /> | |||
| <mimeMap fileExtension=".bin" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".bmp" mimeType="image/bmp" /> | |||
| <mimeMap fileExtension=".c" mimeType="text/plain" /> | |||
| <mimeMap fileExtension=".cab" mimeType="application/vnd.ms-cab-compressed" /> | |||
| <mimeMap fileExtension=".calx" mimeType="application/vnd.ms-office.calx" /> | |||
| <mimeMap fileExtension=".cat" mimeType="application/vnd.ms-pki.seccat" /> | |||
| <mimeMap fileExtension=".cdf" mimeType="application/x-cdf" /> | |||
| <mimeMap fileExtension=".chm" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".class" mimeType="application/x-java-applet" /> | |||
| <mimeMap fileExtension=".clp" mimeType="application/x-msclip" /> | |||
| <mimeMap fileExtension=".cmx" mimeType="image/x-cmx" /> | |||
| <mimeMap fileExtension=".cnf" mimeType="text/plain" /> | |||
| <mimeMap fileExtension=".cod" mimeType="image/cis-cod" /> | |||
| <mimeMap fileExtension=".cpio" mimeType="application/x-cpio" /> | |||
| <mimeMap fileExtension=".cpp" mimeType="text/plain" /> | |||
| <mimeMap fileExtension=".crd" mimeType="application/x-mscardfile" /> | |||
| <mimeMap fileExtension=".crl" mimeType="application/pkix-crl" /> | |||
| <mimeMap fileExtension=".crt" mimeType="application/x-x509-ca-cert" /> | |||
| <mimeMap fileExtension=".csh" mimeType="application/x-csh" /> | |||
| <mimeMap fileExtension=".css" mimeType="text/css" /> | |||
| <mimeMap fileExtension=".csv" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".cur" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".dcr" mimeType="application/x-director" /> | |||
| <mimeMap fileExtension=".deploy" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".der" mimeType="application/x-x509-ca-cert" /> | |||
| <mimeMap fileExtension=".dib" mimeType="image/bmp" /> | |||
| <mimeMap fileExtension=".dir" mimeType="application/x-director" /> | |||
| <mimeMap fileExtension=".disco" mimeType="text/xml" /> | |||
| <mimeMap fileExtension=".dll" mimeType="application/x-msdownload" /> | |||
| <mimeMap fileExtension=".dll.config" mimeType="text/xml" /> | |||
| <mimeMap fileExtension=".dlm" mimeType="text/dlm" /> | |||
| <mimeMap fileExtension=".doc" mimeType="application/msword" /> | |||
| <mimeMap fileExtension=".docm" mimeType="application/vnd.ms-word.document.macroEnabled.12" /> | |||
| <mimeMap fileExtension=".docx" mimeType="application/vnd.openxmlformats-officedocument.wordprocessingml.document" /> | |||
| <mimeMap fileExtension=".dot" mimeType="application/msword" /> | |||
| <mimeMap fileExtension=".dotm" mimeType="application/vnd.ms-word.template.macroEnabled.12" /> | |||
| <mimeMap fileExtension=".dotx" mimeType="application/vnd.openxmlformats-officedocument.wordprocessingml.template" /> | |||
| <mimeMap fileExtension=".dsp" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".dtd" mimeType="text/xml" /> | |||
| <mimeMap fileExtension=".dvi" mimeType="application/x-dvi" /> | |||
| <mimeMap fileExtension=".dvr-ms" mimeType="video/x-ms-dvr" /> | |||
| <mimeMap fileExtension=".dwf" mimeType="drawing/x-dwf" /> | |||
| <mimeMap fileExtension=".dwp" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".dxr" mimeType="application/x-director" /> | |||
| <mimeMap fileExtension=".eml" mimeType="message/rfc822" /> | |||
| <mimeMap fileExtension=".emz" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".eot" mimeType="application/vnd.ms-fontobject" /> | |||
| <mimeMap fileExtension=".eps" mimeType="application/postscript" /> | |||
| <mimeMap fileExtension=".esd" mimeType="application/vnd.ms-cab-compressed" /> | |||
| <mimeMap fileExtension=".etx" mimeType="text/x-setext" /> | |||
| <mimeMap fileExtension=".evy" mimeType="application/envoy" /> | |||
| <mimeMap fileExtension=".exe" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".exe.config" mimeType="text/xml" /> | |||
| <mimeMap fileExtension=".fdf" mimeType="application/vnd.fdf" /> | |||
| <mimeMap fileExtension=".fif" mimeType="application/fractals" /> | |||
| <mimeMap fileExtension=".fla" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".flr" mimeType="x-world/x-vrml" /> | |||
| <mimeMap fileExtension=".flv" mimeType="video/x-flv" /> | |||
| <mimeMap fileExtension=".gif" mimeType="image/gif" /> | |||
| <mimeMap fileExtension=".glb" mimeType="model/gltf-binary" /> | |||
| <mimeMap fileExtension=".gtar" mimeType="application/x-gtar" /> | |||
| <mimeMap fileExtension=".gz" mimeType="application/x-gzip" /> | |||
| <mimeMap fileExtension=".h" mimeType="text/plain" /> | |||
| <mimeMap fileExtension=".hdf" mimeType="application/x-hdf" /> | |||
| <mimeMap fileExtension=".hdml" mimeType="text/x-hdml" /> | |||
| <mimeMap fileExtension=".hhc" mimeType="application/x-oleobject" /> | |||
| <mimeMap fileExtension=".hhk" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".hhp" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".hlp" mimeType="application/winhlp" /> | |||
| <mimeMap fileExtension=".hqx" mimeType="application/mac-binhex40" /> | |||
| <mimeMap fileExtension=".hta" mimeType="application/hta" /> | |||
| <mimeMap fileExtension=".htc" mimeType="text/x-component" /> | |||
| <mimeMap fileExtension=".htm" mimeType="text/html" /> | |||
| <mimeMap fileExtension=".html" mimeType="text/html" /> | |||
| <mimeMap fileExtension=".htt" mimeType="text/webviewhtml" /> | |||
| <mimeMap fileExtension=".hxt" mimeType="text/html" /> | |||
| <mimeMap fileExtension=".ico" mimeType="image/x-icon" /> | |||
| <mimeMap fileExtension=".ics" mimeType="text/calendar" /> | |||
| <mimeMap fileExtension=".ief" mimeType="image/ief" /> | |||
| <mimeMap fileExtension=".iii" mimeType="application/x-iphone" /> | |||
| <mimeMap fileExtension=".inf" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".ins" mimeType="application/x-internet-signup" /> | |||
| <mimeMap fileExtension=".isp" mimeType="application/x-internet-signup" /> | |||
| <mimeMap fileExtension=".IVF" mimeType="video/x-ivf" /> | |||
| <mimeMap fileExtension=".jar" mimeType="application/java-archive" /> | |||
| <mimeMap fileExtension=".java" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".jck" mimeType="application/liquidmotion" /> | |||
| <mimeMap fileExtension=".jcz" mimeType="application/liquidmotion" /> | |||
| <mimeMap fileExtension=".jfif" mimeType="image/pjpeg" /> | |||
| <mimeMap fileExtension=".jpb" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".jpe" mimeType="image/jpeg" /> | |||
| <mimeMap fileExtension=".jpeg" mimeType="image/jpeg" /> | |||
| <mimeMap fileExtension=".jpg" mimeType="image/jpeg" /> | |||
| <mimeMap fileExtension=".js" mimeType="application/javascript" /> | |||
| <mimeMap fileExtension=".json" mimeType="application/json" /> | |||
| <mimeMap fileExtension=".jsonld" mimeType="application/ld+json" /> | |||
| <mimeMap fileExtension=".jsx" mimeType="text/jscript" /> | |||
| <mimeMap fileExtension=".latex" mimeType="application/x-latex" /> | |||
| <mimeMap fileExtension=".less" mimeType="text/css" /> | |||
| <mimeMap fileExtension=".lit" mimeType="application/x-ms-reader" /> | |||
| <mimeMap fileExtension=".lpk" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".lsf" mimeType="video/x-la-asf" /> | |||
| <mimeMap fileExtension=".lsx" mimeType="video/x-la-asf" /> | |||
| <mimeMap fileExtension=".lzh" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".m13" mimeType="application/x-msmediaview" /> | |||
| <mimeMap fileExtension=".m14" mimeType="application/x-msmediaview" /> | |||
| <mimeMap fileExtension=".m1v" mimeType="video/mpeg" /> | |||
| <mimeMap fileExtension=".m2ts" mimeType="video/vnd.dlna.mpeg-tts" /> | |||
| <mimeMap fileExtension=".m3u" mimeType="audio/x-mpegurl" /> | |||
| <mimeMap fileExtension=".m4a" mimeType="audio/mp4" /> | |||
| <mimeMap fileExtension=".m4v" mimeType="video/mp4" /> | |||
| <mimeMap fileExtension=".man" mimeType="application/x-troff-man" /> | |||
| <mimeMap fileExtension=".manifest" mimeType="application/x-ms-manifest" /> | |||
| <mimeMap fileExtension=".map" mimeType="text/plain" /> | |||
| <mimeMap fileExtension=".mdb" mimeType="application/x-msaccess" /> | |||
| <mimeMap fileExtension=".mdp" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".me" mimeType="application/x-troff-me" /> | |||
| <mimeMap fileExtension=".mht" mimeType="message/rfc822" /> | |||
| <mimeMap fileExtension=".mhtml" mimeType="message/rfc822" /> | |||
| <mimeMap fileExtension=".mid" mimeType="audio/mid" /> | |||
| <mimeMap fileExtension=".midi" mimeType="audio/mid" /> | |||
| <mimeMap fileExtension=".mix" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".mmf" mimeType="application/x-smaf" /> | |||
| <mimeMap fileExtension=".mno" mimeType="text/xml" /> | |||
| <mimeMap fileExtension=".mny" mimeType="application/x-msmoney" /> | |||
| <mimeMap fileExtension=".mov" mimeType="video/quicktime" /> | |||
| <mimeMap fileExtension=".movie" mimeType="video/x-sgi-movie" /> | |||
| <mimeMap fileExtension=".mp2" mimeType="video/mpeg" /> | |||
| <mimeMap fileExtension=".mp3" mimeType="audio/mpeg" /> | |||
| <mimeMap fileExtension=".mp4" mimeType="video/mp4" /> | |||
| <mimeMap fileExtension=".mp4v" mimeType="video/mp4" /> | |||
| <mimeMap fileExtension=".mpa" mimeType="video/mpeg" /> | |||
| <mimeMap fileExtension=".mpe" mimeType="video/mpeg" /> | |||
| <mimeMap fileExtension=".mpeg" mimeType="video/mpeg" /> | |||
| <mimeMap fileExtension=".mpg" mimeType="video/mpeg" /> | |||
| <mimeMap fileExtension=".mpp" mimeType="application/vnd.ms-project" /> | |||
| <mimeMap fileExtension=".mpv2" mimeType="video/mpeg" /> | |||
| <mimeMap fileExtension=".ms" mimeType="application/x-troff-ms" /> | |||
| <mimeMap fileExtension=".msi" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".mso" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".mvb" mimeType="application/x-msmediaview" /> | |||
| <mimeMap fileExtension=".mvc" mimeType="application/x-miva-compiled" /> | |||
| <mimeMap fileExtension=".nc" mimeType="application/x-netcdf" /> | |||
| <mimeMap fileExtension=".nsc" mimeType="video/x-ms-asf" /> | |||
| <mimeMap fileExtension=".nws" mimeType="message/rfc822" /> | |||
| <mimeMap fileExtension=".ocx" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".oda" mimeType="application/oda" /> | |||
| <mimeMap fileExtension=".odc" mimeType="text/x-ms-odc" /> | |||
| <mimeMap fileExtension=".ods" mimeType="application/oleobject" /> | |||
| <mimeMap fileExtension=".oga" mimeType="audio/ogg" /> | |||
| <mimeMap fileExtension=".ogg" mimeType="video/ogg" /> | |||
| <mimeMap fileExtension=".ogv" mimeType="video/ogg" /> | |||
| <mimeMap fileExtension=".one" mimeType="application/onenote" /> | |||
| <mimeMap fileExtension=".onea" mimeType="application/onenote" /> | |||
| <mimeMap fileExtension=".onetoc" mimeType="application/onenote" /> | |||
| <mimeMap fileExtension=".onetoc2" mimeType="application/onenote" /> | |||
| <mimeMap fileExtension=".onetmp" mimeType="application/onenote" /> | |||
| <mimeMap fileExtension=".onepkg" mimeType="application/onenote" /> | |||
| <mimeMap fileExtension=".osdx" mimeType="application/opensearchdescription+xml" /> | |||
| <mimeMap fileExtension=".otf" mimeType="font/otf" /> | |||
| <mimeMap fileExtension=".p10" mimeType="application/pkcs10" /> | |||
| <mimeMap fileExtension=".p12" mimeType="application/x-pkcs12" /> | |||
| <mimeMap fileExtension=".p7b" mimeType="application/x-pkcs7-certificates" /> | |||
| <mimeMap fileExtension=".p7c" mimeType="application/pkcs7-mime" /> | |||
| <mimeMap fileExtension=".p7m" mimeType="application/pkcs7-mime" /> | |||
| <mimeMap fileExtension=".p7r" mimeType="application/x-pkcs7-certreqresp" /> | |||
| <mimeMap fileExtension=".p7s" mimeType="application/pkcs7-signature" /> | |||
| <mimeMap fileExtension=".pbm" mimeType="image/x-portable-bitmap" /> | |||
| <mimeMap fileExtension=".pcx" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".pcz" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".pdf" mimeType="application/pdf" /> | |||
| <mimeMap fileExtension=".pfb" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".pfm" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".pfx" mimeType="application/x-pkcs12" /> | |||
| <mimeMap fileExtension=".pgm" mimeType="image/x-portable-graymap" /> | |||
| <mimeMap fileExtension=".pko" mimeType="application/vnd.ms-pki.pko" /> | |||
| <mimeMap fileExtension=".pma" mimeType="application/x-perfmon" /> | |||
| <mimeMap fileExtension=".pmc" mimeType="application/x-perfmon" /> | |||
| <mimeMap fileExtension=".pml" mimeType="application/x-perfmon" /> | |||
| <mimeMap fileExtension=".pmr" mimeType="application/x-perfmon" /> | |||
| <mimeMap fileExtension=".pmw" mimeType="application/x-perfmon" /> | |||
| <mimeMap fileExtension=".png" mimeType="image/png" /> | |||
| <mimeMap fileExtension=".pnm" mimeType="image/x-portable-anymap" /> | |||
| <mimeMap fileExtension=".pnz" mimeType="image/png" /> | |||
| <mimeMap fileExtension=".pot" mimeType="application/vnd.ms-powerpoint" /> | |||
| <mimeMap fileExtension=".potm" mimeType="application/vnd.ms-powerpoint.template.macroEnabled.12" /> | |||
| <mimeMap fileExtension=".potx" mimeType="application/vnd.openxmlformats-officedocument.presentationml.template" /> | |||
| <mimeMap fileExtension=".ppam" mimeType="application/vnd.ms-powerpoint.addin.macroEnabled.12" /> | |||
| <mimeMap fileExtension=".ppm" mimeType="image/x-portable-pixmap" /> | |||
| <mimeMap fileExtension=".pps" mimeType="application/vnd.ms-powerpoint" /> | |||
| <mimeMap fileExtension=".ppsm" mimeType="application/vnd.ms-powerpoint.slideshow.macroEnabled.12" /> | |||
| <mimeMap fileExtension=".ppsx" mimeType="application/vnd.openxmlformats-officedocument.presentationml.slideshow" /> | |||
| <mimeMap fileExtension=".ppt" mimeType="application/vnd.ms-powerpoint" /> | |||
| <mimeMap fileExtension=".pptm" mimeType="application/vnd.ms-powerpoint.presentation.macroEnabled.12" /> | |||
| <mimeMap fileExtension=".pptx" mimeType="application/vnd.openxmlformats-officedocument.presentationml.presentation" /> | |||
| <mimeMap fileExtension=".prf" mimeType="application/pics-rules" /> | |||
| <mimeMap fileExtension=".prm" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".prx" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".ps" mimeType="application/postscript" /> | |||
| <mimeMap fileExtension=".psd" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".psm" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".psp" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".pub" mimeType="application/x-mspublisher" /> | |||
| <mimeMap fileExtension=".qt" mimeType="video/quicktime" /> | |||
| <mimeMap fileExtension=".qtl" mimeType="application/x-quicktimeplayer" /> | |||
| <mimeMap fileExtension=".qxd" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".ra" mimeType="audio/x-pn-realaudio" /> | |||
| <mimeMap fileExtension=".ram" mimeType="audio/x-pn-realaudio" /> | |||
| <mimeMap fileExtension=".rar" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".ras" mimeType="image/x-cmu-raster" /> | |||
| <mimeMap fileExtension=".rf" mimeType="image/vnd.rn-realflash" /> | |||
| <mimeMap fileExtension=".rgb" mimeType="image/x-rgb" /> | |||
| <mimeMap fileExtension=".rm" mimeType="application/vnd.rn-realmedia" /> | |||
| <mimeMap fileExtension=".rmi" mimeType="audio/mid" /> | |||
| <mimeMap fileExtension=".roff" mimeType="application/x-troff" /> | |||
| <mimeMap fileExtension=".rpm" mimeType="audio/x-pn-realaudio-plugin" /> | |||
| <mimeMap fileExtension=".rtf" mimeType="application/rtf" /> | |||
| <mimeMap fileExtension=".rtx" mimeType="text/richtext" /> | |||
| <mimeMap fileExtension=".scd" mimeType="application/x-msschedule" /> | |||
| <mimeMap fileExtension=".sct" mimeType="text/scriptlet" /> | |||
| <mimeMap fileExtension=".sea" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".setpay" mimeType="application/set-payment-initiation" /> | |||
| <mimeMap fileExtension=".setreg" mimeType="application/set-registration-initiation" /> | |||
| <mimeMap fileExtension=".sgml" mimeType="text/sgml" /> | |||
| <mimeMap fileExtension=".sh" mimeType="application/x-sh" /> | |||
| <mimeMap fileExtension=".shar" mimeType="application/x-shar" /> | |||
| <mimeMap fileExtension=".sit" mimeType="application/x-stuffit" /> | |||
| <mimeMap fileExtension=".sldm" mimeType="application/vnd.ms-powerpoint.slide.macroEnabled.12" /> | |||
| <mimeMap fileExtension=".sldx" mimeType="application/vnd.openxmlformats-officedocument.presentationml.slide" /> | |||
| <mimeMap fileExtension=".smd" mimeType="audio/x-smd" /> | |||
| <mimeMap fileExtension=".smi" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".smx" mimeType="audio/x-smd" /> | |||
| <mimeMap fileExtension=".smz" mimeType="audio/x-smd" /> | |||
| <mimeMap fileExtension=".snd" mimeType="audio/basic" /> | |||
| <mimeMap fileExtension=".snp" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".spc" mimeType="application/x-pkcs7-certificates" /> | |||
| <mimeMap fileExtension=".spl" mimeType="application/futuresplash" /> | |||
| <mimeMap fileExtension=".spx" mimeType="audio/ogg" /> | |||
| <mimeMap fileExtension=".src" mimeType="application/x-wais-source" /> | |||
| <mimeMap fileExtension=".ssm" mimeType="application/streamingmedia" /> | |||
| <mimeMap fileExtension=".sst" mimeType="application/vnd.ms-pki.certstore" /> | |||
| <mimeMap fileExtension=".stl" mimeType="application/vnd.ms-pki.stl" /> | |||
| <mimeMap fileExtension=".sv4cpio" mimeType="application/x-sv4cpio" /> | |||
| <mimeMap fileExtension=".sv4crc" mimeType="application/x-sv4crc" /> | |||
| <mimeMap fileExtension=".svg" mimeType="image/svg+xml" /> | |||
| <mimeMap fileExtension=".svgz" mimeType="image/svg+xml" /> | |||
| <mimeMap fileExtension=".swf" mimeType="application/x-shockwave-flash" /> | |||
| <mimeMap fileExtension=".t" mimeType="application/x-troff" /> | |||
| <mimeMap fileExtension=".tar" mimeType="application/x-tar" /> | |||
| <mimeMap fileExtension=".tcl" mimeType="application/x-tcl" /> | |||
| <mimeMap fileExtension=".tex" mimeType="application/x-tex" /> | |||
| <mimeMap fileExtension=".texi" mimeType="application/x-texinfo" /> | |||
| <mimeMap fileExtension=".texinfo" mimeType="application/x-texinfo" /> | |||
| <mimeMap fileExtension=".tgz" mimeType="application/x-compressed" /> | |||
| <mimeMap fileExtension=".thmx" mimeType="application/vnd.ms-officetheme" /> | |||
| <mimeMap fileExtension=".thn" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".tif" mimeType="image/tiff" /> | |||
| <mimeMap fileExtension=".tiff" mimeType="image/tiff" /> | |||
| <mimeMap fileExtension=".toc" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".tr" mimeType="application/x-troff" /> | |||
| <mimeMap fileExtension=".trm" mimeType="application/x-msterminal" /> | |||
| <mimeMap fileExtension=".ts" mimeType="video/vnd.dlna.mpeg-tts" /> | |||
| <mimeMap fileExtension=".tsv" mimeType="text/tab-separated-values" /> | |||
| <mimeMap fileExtension=".ttf" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".tts" mimeType="video/vnd.dlna.mpeg-tts" /> | |||
| <mimeMap fileExtension=".txt" mimeType="text/plain" /> | |||
| <mimeMap fileExtension=".u32" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".uls" mimeType="text/iuls" /> | |||
| <mimeMap fileExtension=".ustar" mimeType="application/x-ustar" /> | |||
| <mimeMap fileExtension=".vbs" mimeType="text/vbscript" /> | |||
| <mimeMap fileExtension=".vcf" mimeType="text/x-vcard" /> | |||
| <mimeMap fileExtension=".vcs" mimeType="text/plain" /> | |||
| <mimeMap fileExtension=".vdx" mimeType="application/vnd.ms-visio.viewer" /> | |||
| <mimeMap fileExtension=".vml" mimeType="text/xml" /> | |||
| <mimeMap fileExtension=".vsd" mimeType="application/vnd.visio" /> | |||
| <mimeMap fileExtension=".vss" mimeType="application/vnd.visio" /> | |||
| <mimeMap fileExtension=".vst" mimeType="application/vnd.visio" /> | |||
| <mimeMap fileExtension=".vsto" mimeType="application/x-ms-vsto" /> | |||
| <mimeMap fileExtension=".vsw" mimeType="application/vnd.visio" /> | |||
| <mimeMap fileExtension=".vsx" mimeType="application/vnd.visio" /> | |||
| <mimeMap fileExtension=".vtx" mimeType="application/vnd.visio" /> | |||
| <mimeMap fileExtension=".wasm" mimeType="application/wasm" /> | |||
| <mimeMap fileExtension=".wav" mimeType="audio/wav" /> | |||
| <mimeMap fileExtension=".wax" mimeType="audio/x-ms-wax" /> | |||
| <mimeMap fileExtension=".wbmp" mimeType="image/vnd.wap.wbmp" /> | |||
| <mimeMap fileExtension=".wcm" mimeType="application/vnd.ms-works" /> | |||
| <mimeMap fileExtension=".wdb" mimeType="application/vnd.ms-works" /> | |||
| <mimeMap fileExtension=".webm" mimeType="video/webm" /> | |||
| <mimeMap fileExtension=".wks" mimeType="application/vnd.ms-works" /> | |||
| <mimeMap fileExtension=".wm" mimeType="video/x-ms-wm" /> | |||
| <mimeMap fileExtension=".wma" mimeType="audio/x-ms-wma" /> | |||
| <mimeMap fileExtension=".wmd" mimeType="application/x-ms-wmd" /> | |||
| <mimeMap fileExtension=".wmf" mimeType="application/x-msmetafile" /> | |||
| <mimeMap fileExtension=".wml" mimeType="text/vnd.wap.wml" /> | |||
| <mimeMap fileExtension=".wmlc" mimeType="application/vnd.wap.wmlc" /> | |||
| <mimeMap fileExtension=".wmls" mimeType="text/vnd.wap.wmlscript" /> | |||
| <mimeMap fileExtension=".wmlsc" mimeType="application/vnd.wap.wmlscriptc" /> | |||
| <mimeMap fileExtension=".wmp" mimeType="video/x-ms-wmp" /> | |||
| <mimeMap fileExtension=".wmv" mimeType="video/x-ms-wmv" /> | |||
| <mimeMap fileExtension=".wmx" mimeType="video/x-ms-wmx" /> | |||
| <mimeMap fileExtension=".wmz" mimeType="application/x-ms-wmz" /> | |||
| <mimeMap fileExtension=".woff" mimeType="font/x-woff" /> | |||
| <mimeMap fileExtension=".woff2" mimeType="application/font-woff2" /> | |||
| <mimeMap fileExtension=".wps" mimeType="application/vnd.ms-works" /> | |||
| <mimeMap fileExtension=".wri" mimeType="application/x-mswrite" /> | |||
| <mimeMap fileExtension=".wrl" mimeType="x-world/x-vrml" /> | |||
| <mimeMap fileExtension=".wrz" mimeType="x-world/x-vrml" /> | |||
| <mimeMap fileExtension=".wsdl" mimeType="text/xml" /> | |||
| <mimeMap fileExtension=".wtv" mimeType="video/x-ms-wtv" /> | |||
| <mimeMap fileExtension=".wvx" mimeType="video/x-ms-wvx" /> | |||
| <mimeMap fileExtension=".x" mimeType="application/directx" /> | |||
| <mimeMap fileExtension=".xaf" mimeType="x-world/x-vrml" /> | |||
| <mimeMap fileExtension=".xaml" mimeType="application/xaml+xml" /> | |||
| <mimeMap fileExtension=".xap" mimeType="application/x-silverlight-app" /> | |||
| <mimeMap fileExtension=".xbap" mimeType="application/x-ms-xbap" /> | |||
| <mimeMap fileExtension=".xbm" mimeType="image/x-xbitmap" /> | |||
| <mimeMap fileExtension=".xdr" mimeType="text/plain" /> | |||
| <mimeMap fileExtension=".xht" mimeType="application/xhtml+xml" /> | |||
| <mimeMap fileExtension=".xhtml" mimeType="application/xhtml+xml" /> | |||
| <mimeMap fileExtension=".xla" mimeType="application/vnd.ms-excel" /> | |||
| <mimeMap fileExtension=".xlam" mimeType="application/vnd.ms-excel.addin.macroEnabled.12" /> | |||
| <mimeMap fileExtension=".xlc" mimeType="application/vnd.ms-excel" /> | |||
| <mimeMap fileExtension=".xlm" mimeType="application/vnd.ms-excel" /> | |||
| <mimeMap fileExtension=".xls" mimeType="application/vnd.ms-excel" /> | |||
| <mimeMap fileExtension=".xlsb" mimeType="application/vnd.ms-excel.sheet.binary.macroEnabled.12" /> | |||
| <mimeMap fileExtension=".xlsm" mimeType="application/vnd.ms-excel.sheet.macroEnabled.12" /> | |||
| <mimeMap fileExtension=".xlsx" mimeType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" /> | |||
| <mimeMap fileExtension=".xlt" mimeType="application/vnd.ms-excel" /> | |||
| <mimeMap fileExtension=".xltm" mimeType="application/vnd.ms-excel.template.macroEnabled.12" /> | |||
| <mimeMap fileExtension=".xltx" mimeType="application/vnd.openxmlformats-officedocument.spreadsheetml.template" /> | |||
| <mimeMap fileExtension=".xlw" mimeType="application/vnd.ms-excel" /> | |||
| <mimeMap fileExtension=".xml" mimeType="text/xml" /> | |||
| <mimeMap fileExtension=".xof" mimeType="x-world/x-vrml" /> | |||
| <mimeMap fileExtension=".xpm" mimeType="image/x-xpixmap" /> | |||
| <mimeMap fileExtension=".xps" mimeType="application/vnd.ms-xpsdocument" /> | |||
| <mimeMap fileExtension=".xsd" mimeType="text/xml" /> | |||
| <mimeMap fileExtension=".xsf" mimeType="text/xml" /> | |||
| <mimeMap fileExtension=".xsl" mimeType="text/xml" /> | |||
| <mimeMap fileExtension=".xslt" mimeType="text/xml" /> | |||
| <mimeMap fileExtension=".xsn" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".xtp" mimeType="application/octet-stream" /> | |||
| <mimeMap fileExtension=".xwd" mimeType="image/x-xwindowdump" /> | |||
| <mimeMap fileExtension=".z" mimeType="application/x-compress" /> | |||
| <mimeMap fileExtension=".zip" mimeType="application/x-zip-compressed" /> | |||
| </staticContent> | |||
| <tracing> | |||
| <traceFailedRequests> | |||
| <add path="*"> | |||
| <traceAreas> | |||
| <add provider="ASP" verbosity="Verbose" /> | |||
| <add provider="ASPNET" areas="Infrastructure,Module,Page,AppServices" verbosity="Verbose" /> | |||
| <add provider="ISAPI Extension" verbosity="Verbose" /> | |||
| <add provider="WWW Server" areas="Authentication,Security,Filter,StaticFile,CGI,Compression,Cache,RequestNotifications,Module,Rewrite,WebSocket" verbosity="Verbose" /> | |||
| </traceAreas> | |||
| <failureDefinitions statusCodes="200-999" /> | |||
| </add> | |||
| </traceFailedRequests> | |||
| <traceProviderDefinitions> | |||
| <add name="WWW Server" guid="{3a2a4e84-4c21-4981-ae10-3fda0d9b0f83}"> | |||
| <areas> | |||
| <clear /> | |||
| <add name="Authentication" value="2" /> | |||
| <add name="Security" value="4" /> | |||
| <add name="Filter" value="8" /> | |||
| <add name="StaticFile" value="16" /> | |||
| <add name="CGI" value="32" /> | |||
| <add name="Compression" value="64" /> | |||
| <add name="Cache" value="128" /> | |||
| <add name="RequestNotifications" value="256" /> | |||
| <add name="Module" value="512" /> | |||
| <add name="Rewrite" value="1024" /> | |||
| <add name="FastCGI" value="4096" /> | |||
| <add name="WebSocket" value="16384" /> | |||
| <add name="ANCM" value="65536" /> | |||
| </areas> | |||
| </add> | |||
| <add name="ASP" guid="{06b94d9a-b15e-456e-a4ef-37c984a2cb4b}"> | |||
| <areas> | |||
| <clear /> | |||
| </areas> | |||
| </add> | |||
| <add name="ISAPI Extension" guid="{a1c2040e-8840-4c31-ba11-9871031a19ea}"> | |||
| <areas> | |||
| <clear /> | |||
| </areas> | |||
| </add> | |||
| <add name="ASPNET" guid="{AFF081FE-0247-4275-9C4E-021F3DC1DA35}"> | |||
| <areas> | |||
| <add name="Infrastructure" value="1" /> | |||
| <add name="Module" value="2" /> | |||
| <add name="Page" value="4" /> | |||
| <add name="AppServices" value="8" /> | |||
| </areas> | |||
| </add> | |||
| </traceProviderDefinitions> | |||
| </tracing> | |||
| <urlCompression /> | |||
| <validation /> | |||
| <webdav> | |||
| <globalSettings> | |||
| <propertyStores> | |||
| <add name="webdav_simple_prop" image="%IIS_BIN%\webdav_simple_prop.dll" image32="%IIS_BIN%\webdav_simple_prop.dll" /> | |||
| </propertyStores> | |||
| <lockStores> | |||
| <add name="webdav_simple_lock" image="%IIS_BIN%\webdav_simple_lock.dll" image32="%IIS_BIN%\webdav_simple_lock.dll" /> | |||
| </lockStores> | |||
| </globalSettings> | |||
| <authoring> | |||
| <locks enabled="true" lockStore="webdav_simple_lock" /> | |||
| </authoring> | |||
| <authoringRules /> | |||
| </webdav> | |||
| <webSocket /> | |||
| <applicationInitialization /> | |||
| </system.webServer> | |||
| <location path="" overrideMode="Allow"> | |||
| <system.webServer> | |||
| <modules> | |||
| <add name="IsapiFilterModule" lockItem="true" /> | |||
| <add name="BasicAuthenticationModule" lockItem="true" /> | |||
| <add name="IsapiModule" lockItem="true" /> | |||
| <add name="HttpLoggingModule" lockItem="true" /> | |||
| <add name="DynamicCompressionModule" lockItem="true" /> | |||
| <add name="StaticCompressionModule" lockItem="true" /> | |||
| <add name="DefaultDocumentModule" lockItem="true" /> | |||
| <add name="DirectoryListingModule" lockItem="true" /> | |||
| <add name="ProtocolSupportModule" lockItem="true" /> | |||
| <add name="HttpRedirectionModule" lockItem="true" /> | |||
| <add name="ServerSideIncludeModule" lockItem="true" /> | |||
| <add name="StaticFileModule" lockItem="true" /> | |||
| <add name="AnonymousAuthenticationModule" lockItem="true" /> | |||
| <add name="CertificateMappingAuthenticationModule" lockItem="true" /> | |||
| <add name="UrlAuthorizationModule" lockItem="true" /> | |||
| <add name="WindowsAuthenticationModule" lockItem="true" /> | |||
| <add name="IISCertificateMappingAuthenticationModule" lockItem="true" /> | |||
| <add name="WebMatrixSupportModule" lockItem="true" /> | |||
| <add name="IpRestrictionModule" lockItem="true" /> | |||
| <add name="DynamicIpRestrictionModule" lockItem="true" /> | |||
| <add name="RequestFilteringModule" lockItem="true" /> | |||
| <add name="CustomLoggingModule" lockItem="true" /> | |||
| <add name="CustomErrorModule" lockItem="true" /> | |||
| <add name="FailedRequestsTracingModule" lockItem="true" /> | |||
| <add name="CgiModule" lockItem="true" /> | |||
| <add name="FastCgiModule" lockItem="true" /> | |||
| <!-- <add name="WebDAVModule" /> --> | |||
| <add name="RewriteModule" /> | |||
| <add name="OutputCache" type="System.Web.Caching.OutputCacheModule" preCondition="managedHandler" /> | |||
| <add name="Session" type="System.Web.SessionState.SessionStateModule" preCondition="managedHandler" /> | |||
| <add name="WindowsAuthentication" type="System.Web.Security.WindowsAuthenticationModule" preCondition="managedHandler" /> | |||
| <add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule" preCondition="managedHandler" /> | |||
| <add name="DefaultAuthentication" type="System.Web.Security.DefaultAuthenticationModule" preCondition="managedHandler" /> | |||
| <add name="RoleManager" type="System.Web.Security.RoleManagerModule" preCondition="managedHandler" /> | |||
| <add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" preCondition="managedHandler" /> | |||
| <add name="FileAuthorization" type="System.Web.Security.FileAuthorizationModule" preCondition="managedHandler" /> | |||
| <add name="AnonymousIdentification" type="System.Web.Security.AnonymousIdentificationModule" preCondition="managedHandler" /> | |||
| <add name="Profile" type="System.Web.Profile.ProfileModule" preCondition="managedHandler" /> | |||
| <add name="UrlMappingsModule" type="System.Web.UrlMappingsModule" preCondition="managedHandler" /> | |||
| <add name="ApplicationInitializationModule" lockItem="true" /> | |||
| <add name="WebSocketModule" lockItem="true" /> | |||
| <add name="ServiceModel-4.0" type="System.ServiceModel.Activation.ServiceHttpModule,System.ServiceModel.Activation,Version=4.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35" preCondition="managedHandler,runtimeVersionv4.0" /> | |||
| <add name="ConfigurationValidationModule" lockItem="true" /> | |||
| <add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition="managedHandler,runtimeVersionv4.0" /> | |||
| <add name="ScriptModule-4.0" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="managedHandler,runtimeVersionv4.0" /> | |||
| <add name="AspNetCoreModuleV2" lockItem="true" /> | |||
| </modules> | |||
| <handlers accessPolicy="Read, Script"> | |||
| <!-- <add name="WebDAV" path="*" verb="PROPFIND,PROPPATCH,MKCOL,PUT,COPY,DELETE,MOVE,LOCK,UNLOCK" modules="WebDAVModule" resourceType="Unspecified" requireAccess="None" /> --> | |||
| <add name="AXD-ISAPI-4.0_64bit" path="*.axd" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" /> | |||
| <add name="PageHandlerFactory-ISAPI-4.0_64bit" path="*.aspx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" /> | |||
| <add name="SimpleHandlerFactory-ISAPI-4.0_64bit" path="*.ashx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" /> | |||
| <add name="WebServiceHandlerFactory-ISAPI-4.0_64bit" path="*.asmx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" /> | |||
| <add name="HttpRemotingHandlerFactory-rem-ISAPI-4.0_64bit" path="*.rem" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" /> | |||
| <add name="HttpRemotingHandlerFactory-soap-ISAPI-4.0_64bit" path="*.soap" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" /> | |||
| <add name="svc-ISAPI-4.0_64bit" path="*.svc" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" /> | |||
| <add name="rules-ISAPI-4.0_64bit" path="*.rules" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" /> | |||
| <add name="xoml-ISAPI-4.0_64bit" path="*.xoml" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" /> | |||
| <add name="xamlx-ISAPI-4.0_64bit" path="*.xamlx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" /> | |||
| <add name="aspq-ISAPI-4.0_64bit" path="*.aspq" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" /> | |||
| <add name="cshtm-ISAPI-4.0_64bit" path="*.cshtm" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" /> | |||
| <add name="cshtml-ISAPI-4.0_64bit" path="*.cshtml" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" /> | |||
| <add name="vbhtm-ISAPI-4.0_64bit" path="*.vbhtm" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" /> | |||
| <add name="vbhtml-ISAPI-4.0_64bit" path="*.vbhtml" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" /> | |||
| <add name="AXD-ISAPI-4.0_32bit" path="*.axd" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" /> | |||
| <add name="PageHandlerFactory-ISAPI-4.0_32bit" path="*.aspx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" /> | |||
| <add name="SimpleHandlerFactory-ISAPI-4.0_32bit" path="*.ashx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" /> | |||
| <add name="WebServiceHandlerFactory-ISAPI-4.0_32bit" path="*.asmx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" /> | |||
| <add name="HttpRemotingHandlerFactory-rem-ISAPI-4.0_32bit" path="*.rem" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" /> | |||
| <add name="HttpRemotingHandlerFactory-soap-ISAPI-4.0_32bit" path="*.soap" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" /> | |||
| <add name="svc-ISAPI-4.0_32bit" path="*.svc" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" /> | |||
| <add name="rules-ISAPI-4.0_32bit" path="*.rules" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" /> | |||
| <add name="xoml-ISAPI-4.0_32bit" path="*.xoml" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" /> | |||
| <add name="xamlx-ISAPI-4.0_32bit" path="*.xamlx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" /> | |||
| <add name="aspq-ISAPI-4.0_32bit" path="*.aspq" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" /> | |||
| <add name="cshtm-ISAPI-4.0_32bit" path="*.cshtm" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" /> | |||
| <add name="cshtml-ISAPI-4.0_32bit" path="*.cshtml" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" /> | |||
| <add name="vbhtm-ISAPI-4.0_32bit" path="*.vbhtm" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" /> | |||
| <add name="vbhtml-ISAPI-4.0_32bit" path="*.vbhtml" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" /> | |||
| <add name="TraceHandler-Integrated-4.0" path="trace.axd" verb="GET,HEAD,POST,DEBUG" type="System.Web.Handlers.TraceHandler" preCondition="integratedMode,runtimeVersionv4.0" /> | |||
| <add name="WebAdminHandler-Integrated-4.0" path="WebAdmin.axd" verb="GET,DEBUG" type="System.Web.Handlers.WebAdminHandler" preCondition="integratedMode,runtimeVersionv4.0" /> | |||
| <add name="AssemblyResourceLoader-Integrated-4.0" path="WebResource.axd" verb="GET,DEBUG" type="System.Web.Handlers.AssemblyResourceLoader" preCondition="integratedMode,runtimeVersionv4.0" /> | |||
| <add name="PageHandlerFactory-Integrated-4.0" path="*.aspx" verb="GET,HEAD,POST,DEBUG" type="System.Web.UI.PageHandlerFactory" preCondition="integratedMode,runtimeVersionv4.0" /> | |||
| <add name="SimpleHandlerFactory-Integrated-4.0" path="*.ashx" verb="GET,HEAD,POST,DEBUG" type="System.Web.UI.SimpleHandlerFactory" preCondition="integratedMode,runtimeVersionv4.0" /> | |||
| <add name="WebServiceHandlerFactory-Integrated-4.0" path="*.asmx" verb="GET,HEAD,POST,DEBUG" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="integratedMode,runtimeVersionv4.0" /> | |||
| <add name="HttpRemotingHandlerFactory-rem-Integrated-4.0" path="*.rem" verb="GET,HEAD,POST,DEBUG" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory, System.Runtime.Remoting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="integratedMode,runtimeVersionv4.0" /> | |||
| <add name="HttpRemotingHandlerFactory-soap-Integrated-4.0" path="*.soap" verb="GET,HEAD,POST,DEBUG" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory, System.Runtime.Remoting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="integratedMode,runtimeVersionv4.0" /> | |||
| <add name="svc-Integrated-4.0" path="*.svc" verb="*" type="System.ServiceModel.Activation.ServiceHttpHandlerFactory, System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="integratedMode,runtimeVersionv4.0" /> | |||
| <add name="rules-Integrated-4.0" path="*.rules" verb="*" type="System.ServiceModel.Activation.ServiceHttpHandlerFactory, System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="integratedMode,runtimeVersionv4.0" /> | |||
| <add name="xoml-Integrated-4.0" path="*.xoml" verb="*" type="System.ServiceModel.Activation.ServiceHttpHandlerFactory, System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="integratedMode,runtimeVersionv4.0" /> | |||
| <add name="xamlx-Integrated-4.0" path="*.xamlx" verb="GET,HEAD,POST,DEBUG" type="System.Xaml.Hosting.XamlHttpHandlerFactory, System.Xaml.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="integratedMode,runtimeVersionv4.0" /> | |||
| <add name="aspq-Integrated-4.0" path="*.aspq" verb="GET,HEAD,POST,DEBUG" type="System.Web.HttpForbiddenHandler" preCondition="integratedMode,runtimeVersionv4.0" /> | |||
| <add name="cshtm-Integrated-4.0" path="*.cshtm" verb="GET,HEAD,POST,DEBUG" type="System.Web.HttpForbiddenHandler" preCondition="integratedMode,runtimeVersionv4.0" /> | |||
| <add name="cshtml-Integrated-4.0" path="*.cshtml" verb="GET,HEAD,POST,DEBUG" type="System.Web.HttpForbiddenHandler" preCondition="integratedMode,runtimeVersionv4.0" /> | |||
| <add name="vbhtm-Integrated-4.0" path="*.vbhtm" verb="GET,HEAD,POST,DEBUG" type="System.Web.HttpForbiddenHandler" preCondition="integratedMode,runtimeVersionv4.0" /> | |||
| <add name="vbhtml-Integrated-4.0" path="*.vbhtml" verb="GET,HEAD,POST,DEBUG" type="System.Web.HttpForbiddenHandler" preCondition="integratedMode,runtimeVersionv4.0" /> | |||
| <add name="ScriptHandlerFactoryAppServices-Integrated-4.0" path="*_AppService.axd" verb="*" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" preCondition="integratedMode,runtimeVersionv4.0" /> | |||
| <add name="ScriptResourceIntegrated-4.0" path="*ScriptResource.axd" verb="GET,HEAD" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" preCondition="integratedMode,runtimeVersionv4.0" /> | |||
| <add name="ASPClassic" path="*.asp" verb="GET,HEAD,POST" modules="IsapiModule" scriptProcessor="%IIS_BIN%\asp.dll" resourceType="File" /> | |||
| <add name="SecurityCertificate" path="*.cer" verb="GET,HEAD,POST" modules="IsapiModule" scriptProcessor="%IIS_BIN%\asp.dll" resourceType="File" /> | |||
| <add name="ISAPI-dll" path="*.dll" verb="*" modules="IsapiModule" resourceType="File" requireAccess="Execute" allowPathInfo="true" /> | |||
| <add name="TraceHandler-Integrated" path="trace.axd" verb="GET,HEAD,POST,DEBUG" type="System.Web.Handlers.TraceHandler" preCondition="integratedMode,runtimeVersionv2.0" /> | |||
| <add name="WebAdminHandler-Integrated" path="WebAdmin.axd" verb="GET,DEBUG" type="System.Web.Handlers.WebAdminHandler" preCondition="integratedMode,runtimeVersionv2.0" /> | |||
| <add name="AssemblyResourceLoader-Integrated" path="WebResource.axd" verb="GET,DEBUG" type="System.Web.Handlers.AssemblyResourceLoader" preCondition="integratedMode,runtimeVersionv2.0" /> | |||
| <add name="PageHandlerFactory-Integrated" path="*.aspx" verb="GET,HEAD,POST,DEBUG" type="System.Web.UI.PageHandlerFactory" preCondition="integratedMode,runtimeVersionv2.0" /> | |||
| <add name="SimpleHandlerFactory-Integrated" path="*.ashx" verb="GET,HEAD,POST,DEBUG" type="System.Web.UI.SimpleHandlerFactory" preCondition="integratedMode,runtimeVersionv2.0" /> | |||
| <add name="WebServiceHandlerFactory-Integrated" path="*.asmx" verb="GET,HEAD,POST,DEBUG" type="System.Web.Services.Protocols.WebServiceHandlerFactory,System.Web.Services,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" preCondition="integratedMode,runtimeVersionv2.0" /> | |||
| <add name="HttpRemotingHandlerFactory-rem-Integrated" path="*.rem" verb="GET,HEAD,POST,DEBUG" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory,System.Runtime.Remoting,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089" preCondition="integratedMode,runtimeVersionv2.0" /> | |||
| <add name="HttpRemotingHandlerFactory-soap-Integrated" path="*.soap" verb="GET,HEAD,POST,DEBUG" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory,System.Runtime.Remoting,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089" preCondition="integratedMode,runtimeVersionv2.0" /> | |||
| <add name="AXD-ISAPI-2.0" path="*.axd" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" responseBufferLimit="0" /> | |||
| <add name="PageHandlerFactory-ISAPI-2.0" path="*.aspx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" responseBufferLimit="0" /> | |||
| <add name="SimpleHandlerFactory-ISAPI-2.0" path="*.ashx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" responseBufferLimit="0" /> | |||
| <add name="WebServiceHandlerFactory-ISAPI-2.0" path="*.asmx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" responseBufferLimit="0" /> | |||
| <add name="HttpRemotingHandlerFactory-rem-ISAPI-2.0" path="*.rem" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" responseBufferLimit="0" /> | |||
| <add name="HttpRemotingHandlerFactory-soap-ISAPI-2.0" path="*.soap" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" responseBufferLimit="0" /> | |||
| <add name="AXD-ISAPI-2.0-64" path="*.axd" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" responseBufferLimit="0" /> | |||
| <add name="PageHandlerFactory-ISAPI-2.0-64" path="*.aspx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" responseBufferLimit="0" /> | |||
| <add name="SimpleHandlerFactory-ISAPI-2.0-64" path="*.ashx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" responseBufferLimit="0" /> | |||
| <add name="WebServiceHandlerFactory-ISAPI-2.0-64" path="*.asmx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" responseBufferLimit="0" /> | |||
| <add name="HttpRemotingHandlerFactory-rem-ISAPI-2.0-64" path="*.rem" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" responseBufferLimit="0" /> | |||
| <add name="HttpRemotingHandlerFactory-soap-ISAPI-2.0-64" path="*.soap" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" responseBufferLimit="0" /> | |||
| <add name="CGI-exe" path="*.exe" verb="*" modules="CgiModule" resourceType="File" requireAccess="Execute" allowPathInfo="true" /> | |||
| <add name="SSINC-stm" path="*.stm" verb="GET,HEAD,POST" modules="ServerSideIncludeModule" resourceType="File" /> | |||
| <add name="SSINC-shtm" path="*.shtm" verb="GET,HEAD,POST" modules="ServerSideIncludeModule" resourceType="File" /> | |||
| <add name="SSINC-shtml" path="*.shtml" verb="GET,HEAD,POST" modules="ServerSideIncludeModule" resourceType="File" /> | |||
| <add name="TRACEVerbHandler" path="*" verb="TRACE" modules="ProtocolSupportModule" requireAccess="None" /> | |||
| <add name="OPTIONSVerbHandler" path="*" verb="OPTIONS" modules="ProtocolSupportModule" requireAccess="None" /> | |||
| <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" /> | |||
| <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" /> | |||
| <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" responseBufferLimit="0" /> | |||
| <add name="StaticFile" path="*" verb="*" modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" resourceType="Either" requireAccess="Read" /> | |||
| </handlers> | |||
| </system.webServer> | |||
| </location> | |||
| <location path="MVCTemplate" inheritInChildApplications="false"> | |||
| <system.webServer> | |||
| <modules> | |||
| <remove name="WebMatrixSupportModule" /> | |||
| </modules> | |||
| <handlers> | |||
| <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" /> | |||
| </handlers> | |||
| <aspNetCore processPath="%LAUNCHER_PATH%" stdoutLogEnabled="false" hostingModel="InProcess" startupTimeLimit="3600" requestTimeout="23:00:00" /> | |||
| <httpCompression> | |||
| <dynamicTypes> | |||
| <add mimeType="text/event-stream" enabled="false" /> | |||
| </dynamicTypes> | |||
| </httpCompression> | |||
| </system.webServer> | |||
| </location> | |||
| </configuration> | |||
| @@ -1,6 +0,0 @@ | |||
| { | |||
| "ExpandedNodes": [ | |||
| "" | |||
| ], | |||
| "PreviewInSolutionExplorer": false | |||
| } | |||
| @@ -1,13 +1,6 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| using System.Text; | |||
| using System.Threading.Tasks; | |||
| namespace SecureSharing.Business.Dtos; | |||
| namespace SecureSharing.Business.Dtos | |||
| public class BaseDto | |||
| { | |||
| public class BaseDto | |||
| { | |||
| public int Id { get; set; } | |||
| } | |||
| } | |||
| public int Id { get; set; } | |||
| } | |||
| @@ -1,17 +1,11 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| using System.Text; | |||
| using System.Threading.Tasks; | |||
| namespace SecureSharing.Business.Dtos | |||
| { | |||
| public class MessageDto:BaseDto | |||
| { | |||
| public string Text { get; set; } | |||
| public bool IsValid { get; set; } = true; | |||
| namespace SecureSharing.Business.Dtos; | |||
| public DateTime? ExpiryDate { get; set; } | |||
| public sealed class MessageDto : BaseDto | |||
| { | |||
| public string Text { get; set; } | |||
| public bool IsValid { get; set; } = true; | |||
| } | |||
| } | |||
| public DateTime? ExpiryDate { get; set; } | |||
| } | |||
| @@ -1,33 +1,22 @@ | |||
| using AutoMapper; | |||
| using Microsoft.Extensions.DependencyInjection; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| using System.Text; | |||
| using System.Threading.Tasks; | |||
| namespace SecureSharing.Business.Infrastructure.Extensions; | |||
| namespace SecureSharing.Business.Infrastructure.Extensions | |||
| public sealed class StartupExtensions | |||
| { | |||
| public class StartupExtensions | |||
| public static void ConfigureServices(IServiceCollection services) | |||
| { | |||
| public static void ConfigureServices(IServiceCollection services) | |||
| { | |||
| Data.Extensions.StartupExtensions.ConfigureServices(services); | |||
| Data.Extensions.StartupExtensions.ConfigureServices(services); | |||
| // TODO: add all missing services | |||
| // TODO: add all missing services | |||
| var mapperConfiguration = new MapperConfiguration(mc => | |||
| { | |||
| mc.AddProfile(new MapperProfile()); | |||
| }); | |||
| var mapperConfiguration = new MapperConfiguration(mc => { mc.AddProfile(new MapperProfile()); }); | |||
| IMapper mapper = mapperConfiguration.CreateMapper(); | |||
| services.AddSingleton(mapper); | |||
| var mapper = mapperConfiguration.CreateMapper(); | |||
| services.AddSingleton(mapper); | |||
| //services.AddLocalization(options => options.ResourcesPath = "Infrastructure/Resources"); | |||
| } | |||
| //services.AddLocalization(options => options.ResourcesPath = "Infrastructure/Resources"); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,19 +1,13 @@ | |||
| using AutoMapper; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| using System.Text; | |||
| using System.Threading.Tasks; | |||
| using SecureSharing.Data.Data; | |||
| using SecureSharing.Business.Dtos; | |||
| using SecureSharing.Data.Data; | |||
| namespace SecureSharing.Business.Infrastructure; | |||
| namespace SecureSharing.Business.Infrastructure | |||
| public sealed class MapperProfile : Profile | |||
| { | |||
| public class MapperProfile : Profile | |||
| public MapperProfile() | |||
| { | |||
| public MapperProfile() | |||
| { | |||
| CreateMap<Message, MessageDto>().ReverseMap(); | |||
| } | |||
| CreateMap<Message, MessageDto>().ReverseMap(); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,11 +1,9 @@ | |||
| | |||
| namespace SecureSharing.Business.Infrastructure | |||
| namespace SecureSharing.Business.Infrastructure; | |||
| public enum PeriodOfValidity | |||
| { | |||
| public enum PeriodOfValidity | |||
| { | |||
| ONE_TIME, | |||
| ONE_HOUR, | |||
| ONE_DAY, | |||
| ONE_WEEK | |||
| } | |||
| } | |||
| ONE_TIME, | |||
| ONE_HOUR, | |||
| ONE_DAY, | |||
| ONE_WEEK | |||
| } | |||
| @@ -1,13 +1,12 @@ | |||
| namespace SecureSharing.Business.Infrastructure.Settings | |||
| namespace SecureSharing.Business.Infrastructure.Settings; | |||
| public sealed class EmailSettings | |||
| { | |||
| public class EmailSettings | |||
| { | |||
| public string SmtpServer { get; set; } | |||
| public int SmtpPort { get; set; } | |||
| public bool SmtpUseSSL { get; set; } | |||
| public string SmtpUsername { get; set; } | |||
| public string SmtpPassword { get; set; } | |||
| public string SmtpFrom { get; set; } | |||
| public string SmtpFromName { get; set; } | |||
| } | |||
| } | |||
| public string SmtpServer { get; set; } | |||
| public int SmtpPort { get; set; } | |||
| public bool SmtpUseSSL { get; set; } | |||
| public string SmtpUsername { get; set; } | |||
| public string SmtpPassword { get; set; } | |||
| public string SmtpFrom { get; set; } | |||
| public string SmtpFromName { get; set; } | |||
| } | |||
| @@ -1,29 +1,29 @@ | |||
| using System; | |||
| using Microsoft.Extensions.Configuration; | |||
| using Microsoft.Extensions.DependencyInjection; | |||
| using System; | |||
| namespace SecureSharing.Business.Infrastructure | |||
| namespace SecureSharing.Business.Infrastructure; | |||
| public sealed class StartupConfiguration | |||
| { | |||
| public class StartupConfiguration | |||
| public static TConfig ConfigureStartupConfig<TConfig>(IServiceCollection services, IConfiguration configuration) | |||
| where TConfig : class, new() | |||
| { | |||
| public static TConfig ConfigureStartupConfig<TConfig>(IServiceCollection services, IConfiguration configuration) where TConfig : class, new() | |||
| { | |||
| if (services == null) | |||
| throw new ArgumentNullException(nameof(services)); | |||
| if (services == null) | |||
| throw new ArgumentNullException(nameof(services)); | |||
| if (configuration == null) | |||
| throw new ArgumentNullException(nameof(configuration)); | |||
| if (configuration == null) | |||
| throw new ArgumentNullException(nameof(configuration)); | |||
| //create instance of config | |||
| var config = new TConfig(); | |||
| var classType = typeof(TConfig); | |||
| //bind it to the appropriate section of configuration | |||
| configuration.Bind(classType.Name, config); | |||
| //create instance of config | |||
| var config = new TConfig(); | |||
| var classType = typeof(TConfig); | |||
| //bind it to the appropriate section of configuration | |||
| configuration.Bind(classType.Name, config); | |||
| //and register it as a service | |||
| services.AddSingleton(config); | |||
| //and register it as a service | |||
| services.AddSingleton(config); | |||
| return config; | |||
| } | |||
| return config; | |||
| } | |||
| } | |||
| @@ -1,23 +1,19 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| using System.Text; | |||
| using System.Collections.Generic; | |||
| using System.Threading.Tasks; | |||
| using SecureSharing.Business.Dtos; | |||
| using SecureSharing.Business.Infrastructure; | |||
| namespace SecureSharing.Business.Interfaces | |||
| namespace SecureSharing.Business.Interfaces; | |||
| public interface IMessageService | |||
| { | |||
| public interface IMessageService | |||
| { | |||
| public Task<IEnumerable<MessageDto>> GetAll(); | |||
| public Task<int> Create(MessageDto messageDto, PeriodOfValidity chosenPeriod); | |||
| public Task DeleteExpiredMessages(); | |||
| public Task InvalidateMessage(int id); | |||
| public Task Update(MessageDto messageDto); | |||
| public Task<IEnumerable<MessageDto>> GetAll(); | |||
| public Task<int> Create(MessageDto messageDto, PeriodOfValidity chosenPeriod); | |||
| public Task DeleteExpiredMessages(); | |||
| public Task InvalidateMessage(int id); | |||
| public Task Update(MessageDto messageDto); | |||
| public Task<MessageDto> GetById(int messageDto); | |||
| public Task<MessageDto> GetById(int messageDto); | |||
| public Task<bool> Delete(int messageDto); | |||
| } | |||
| } | |||
| public Task<bool> Delete(int messageDto); | |||
| } | |||
| @@ -1,21 +1,21 @@ | |||
| <Project Sdk="Microsoft.NET.Sdk"> | |||
| <PropertyGroup> | |||
| <TargetFramework>net6.0</TargetFramework> | |||
| <RootNamespace>SecureSharing.Business</RootNamespace> | |||
| </PropertyGroup> | |||
| <PropertyGroup> | |||
| <TargetFramework>net6.0</TargetFramework> | |||
| <RootNamespace>SecureSharing.Business</RootNamespace> | |||
| </PropertyGroup> | |||
| <ItemGroup> | |||
| <PackageReference Include="AutoMapper" Version="11.0.1" /> | |||
| <PackageReference Include="MailKit" Version="3.4.1" /> | |||
| <PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="6.0.9" /> | |||
| <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.9" /> | |||
| <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="6.0.0" /> | |||
| <PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.0" /> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <PackageReference Include="AutoMapper" Version="11.0.1"/> | |||
| <PackageReference Include="MailKit" Version="3.4.1"/> | |||
| <PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="6.0.9"/> | |||
| <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.9"/> | |||
| <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="6.0.0"/> | |||
| <PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.0"/> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <ProjectReference Include="..\SecureSharing.Data\SecureSharing.Data.csproj" /> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <ProjectReference Include="..\SecureSharing.Data\SecureSharing.Data.csproj"/> | |||
| </ItemGroup> | |||
| </Project> | |||
| @@ -1,106 +1,106 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| using System.Text; | |||
| using System.Threading.Tasks; | |||
| using AutoMapper; | |||
| using Microsoft.EntityFrameworkCore; | |||
| using SecureSharing.Business.Dtos; | |||
| using SecureSharing.Business.Infrastructure; | |||
| using SecureSharing.Business.Interfaces; | |||
| using SecureSharing.Data.Data; | |||
| using SecureSharing.Data.DbContexts; | |||
| using Microsoft.EntityFrameworkCore; | |||
| using SecureSharing.Business.Infrastructure; | |||
| namespace SecureSharing.Business.Services | |||
| namespace SecureSharing.Business.Services; | |||
| public sealed class MessageService : IMessageService | |||
| { | |||
| public class MessageService:IMessageService | |||
| private readonly AppDbContext _dbContext; | |||
| private readonly IMapper _mapper; | |||
| public MessageService(AppDbContext dbContext, IMapper mapper) | |||
| { | |||
| private readonly AppDbContext _dbContext; | |||
| private readonly IMapper _mapper; | |||
| public MessageService(AppDbContext dbContext, IMapper mapper) | |||
| { | |||
| _dbContext = dbContext; | |||
| _mapper = mapper; | |||
| } | |||
| public async Task<int> Create(MessageDto messageDto, PeriodOfValidity chosenPeriod) | |||
| { | |||
| Message message = _mapper.Map<Message>(messageDto); | |||
| switch (chosenPeriod) | |||
| { | |||
| case (PeriodOfValidity.ONE_TIME): | |||
| message.ExpiryDate = null; | |||
| break; | |||
| case PeriodOfValidity.ONE_DAY: | |||
| message.ExpiryDate = DateTime.UtcNow.AddMinutes(1); | |||
| break; | |||
| case PeriodOfValidity.ONE_HOUR: | |||
| message.ExpiryDate = DateTime.UtcNow.AddHours(1); | |||
| break; | |||
| case PeriodOfValidity.ONE_WEEK: | |||
| message.ExpiryDate = DateTime.UtcNow.AddDays(7); | |||
| break; | |||
| default: | |||
| message.ExpiryDate = null; | |||
| break; | |||
| } | |||
| await _dbContext.Messages.AddAsync(message); | |||
| await _dbContext.SaveChangesAsync(); | |||
| return message.Id; | |||
| } | |||
| _dbContext = dbContext; | |||
| _mapper = mapper; | |||
| } | |||
| public async Task DeleteExpiredMessages() | |||
| public async Task<int> Create(MessageDto messageDto, PeriodOfValidity chosenPeriod) | |||
| { | |||
| var message = _mapper.Map<Message>(messageDto); | |||
| switch (chosenPeriod) | |||
| { | |||
| var result = await _dbContext.Messages.Where(m =>(m.ExpiryDate != null && m.ExpiryDate <= DateTime.UtcNow)||(!m.IsValid) ).ToListAsync(); | |||
| _dbContext.RemoveRange(result); | |||
| await _dbContext.SaveChangesAsync(); | |||
| case PeriodOfValidity.ONE_TIME: | |||
| message.ExpiryDate = null; | |||
| break; | |||
| case PeriodOfValidity.ONE_DAY: | |||
| message.ExpiryDate = DateTime.UtcNow.AddMinutes(1); | |||
| break; | |||
| case PeriodOfValidity.ONE_HOUR: | |||
| message.ExpiryDate = DateTime.UtcNow.AddHours(1); | |||
| break; | |||
| case PeriodOfValidity.ONE_WEEK: | |||
| message.ExpiryDate = DateTime.UtcNow.AddDays(7); | |||
| break; | |||
| default: | |||
| message.ExpiryDate = null; | |||
| break; | |||
| } | |||
| public async Task InvalidateMessage(int id) | |||
| { | |||
| var message = await _dbContext.Messages.Where(m => m.Id == id).FirstOrDefaultAsync(); | |||
| message.IsValid = false; | |||
| await _dbContext.SaveChangesAsync(); | |||
| } | |||
| await _dbContext.Messages.AddAsync(message); | |||
| await _dbContext.SaveChangesAsync(); | |||
| return message.Id; | |||
| } | |||
| public async Task DeleteExpiredMessages() | |||
| { | |||
| var result = await _dbContext.Messages | |||
| .Where(m => (m.ExpiryDate != null && m.ExpiryDate <= DateTime.UtcNow) || !m.IsValid).ToListAsync(); | |||
| _dbContext.RemoveRange(result); | |||
| await _dbContext.SaveChangesAsync(); | |||
| } | |||
| public async Task InvalidateMessage(int id) | |||
| { | |||
| var message = await _dbContext.Messages.Where(m => m.Id == id).FirstOrDefaultAsync(); | |||
| message.IsValid = false; | |||
| await _dbContext.SaveChangesAsync(); | |||
| } | |||
| public async Task<bool> Delete(int messageId) | |||
| public async Task<bool> Delete(int messageId) | |||
| { | |||
| var messageDto = await GetById(messageId); | |||
| if (messageDto == null) return false; | |||
| _dbContext.Set<Message>().Remove(_mapper.Map<Message>(messageDto)); | |||
| try | |||
| { | |||
| MessageDto messageDto = await GetById(messageId); | |||
| if (messageDto == null) return false; | |||
| _dbContext.Set<Message>().Remove(_mapper.Map<Message>(messageDto)); | |||
| try | |||
| { | |||
| await _dbContext.SaveChangesAsync(); | |||
| } | |||
| catch (Microsoft.EntityFrameworkCore.DbUpdateException) | |||
| { | |||
| return false; | |||
| } | |||
| return true; | |||
| await _dbContext.SaveChangesAsync(); | |||
| } | |||
| public async Task<IEnumerable<MessageDto>> GetAll() | |||
| catch (DbUpdateException) | |||
| { | |||
| var result = await _dbContext.Messages.AsNoTracking().ToListAsync(); | |||
| var mappedResult = _mapper.Map<IEnumerable<MessageDto>>(result); | |||
| return mappedResult; | |||
| return false; | |||
| } | |||
| return true; | |||
| } | |||
| public async Task<MessageDto> GetById(int messageId) | |||
| { | |||
| var result = await _dbContext.Messages.AsNoTracking().FirstOrDefaultAsync(x => x.Id == messageId); | |||
| var mappedResult = _mapper.Map<MessageDto>(result); | |||
| return mappedResult; | |||
| } | |||
| public async Task<IEnumerable<MessageDto>> GetAll() | |||
| { | |||
| var result = await _dbContext.Messages.AsNoTracking().ToListAsync(); | |||
| var mappedResult = _mapper.Map<IEnumerable<MessageDto>>(result); | |||
| return mappedResult; | |||
| } | |||
| public async Task Update(MessageDto messageDto) | |||
| { | |||
| var a = _dbContext.Messages.Update(_mapper.Map<Message>(messageDto)); | |||
| await _dbContext.SaveChangesAsync(); | |||
| } | |||
| public async Task<MessageDto> GetById(int messageId) | |||
| { | |||
| var result = await _dbContext.Messages.AsNoTracking().FirstOrDefaultAsync(x => x.Id == messageId); | |||
| var mappedResult = _mapper.Map<MessageDto>(result); | |||
| return mappedResult; | |||
| } | |||
| public async Task Update(MessageDto messageDto) | |||
| { | |||
| var a = _dbContext.Messages.Update(_mapper.Map<Message>(messageDto)); | |||
| await _dbContext.SaveChangesAsync(); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,15 +1,10 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| using System.Text; | |||
| using System.Threading.Tasks; | |||
| namespace SecureSharing.Data.Data | |||
| namespace SecureSharing.Data.Data; | |||
| public sealed class Message : BaseEntity | |||
| { | |||
| public class Message:BaseEntity | |||
| { | |||
| public string Text { get; set; } | |||
| public bool IsValid { get; set; } | |||
| public DateTime? ExpiryDate { get; set; } | |||
| } | |||
| } | |||
| public string Text { get; set; } | |||
| public bool IsValid { get; set; } | |||
| public DateTime? ExpiryDate { get; set; } | |||
| } | |||
| @@ -1,21 +1,14 @@ | |||
| using Microsoft.AspNetCore.Identity.EntityFrameworkCore; | |||
| using Microsoft.EntityFrameworkCore; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using SecureSharing.Data.Data; | |||
| using System.Linq; | |||
| using System.Text; | |||
| using System.Threading.Tasks; | |||
| namespace SecureSharing.Data.DbContexts | |||
| namespace SecureSharing.Data.DbContexts; | |||
| public sealed class AppDbContext : IdentityDbContext | |||
| { | |||
| public class AppDbContext : IdentityDbContext | |||
| public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) | |||
| { | |||
| public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { } | |||
| public DbSet<Message> Messages { get; set; } | |||
| } | |||
| } | |||
| public DbSet<Message> Messages { get; set; } | |||
| } | |||
| @@ -1,26 +1,19 @@ | |||
| using Microsoft.Extensions.DependencyInjection; | |||
| using Microsoft.EntityFrameworkCore; | |||
| using Microsoft.EntityFrameworkCore; | |||
| using Microsoft.Extensions.Configuration; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| using System.Text; | |||
| using System.Threading.Tasks; | |||
| using Microsoft.Extensions.DependencyInjection; | |||
| using SecureSharing.Data.DbContexts; | |||
| using Microsoft.AspNetCore.Identity; | |||
| namespace SecureSharing.Data.Extensions | |||
| namespace SecureSharing.Data.Extensions; | |||
| public sealed class StartupExtensions | |||
| { | |||
| public class StartupExtensions | |||
| public static void ConfigureServices(IServiceCollection services) | |||
| { | |||
| public static void ConfigureServices(IServiceCollection services) | |||
| { | |||
| var configuration = new ConfigurationBuilder() | |||
| .AddJsonFile(path: "appsettings.json") | |||
| .Build(); | |||
| services.AddDbContext<AppDbContext>(options => | |||
| options.UseSqlServer( | |||
| configuration.GetConnectionString("DefaultConnection"))); | |||
| } | |||
| var configuration = new ConfigurationBuilder() | |||
| .AddJsonFile("appsettings.json") | |||
| .Build(); | |||
| services.AddDbContext<AppDbContext>(options => | |||
| options.UseSqlServer( | |||
| configuration.GetConnectionString("DefaultConnection"))); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,22 +1,22 @@ | |||
| <Project Sdk="Microsoft.NET.Sdk"> | |||
| <PropertyGroup> | |||
| <TargetFramework>net6.0</TargetFramework> | |||
| <RootNamespace>SecureSharing.Data</RootNamespace> | |||
| </PropertyGroup> | |||
| <PropertyGroup> | |||
| <TargetFramework>net6.0</TargetFramework> | |||
| <RootNamespace>SecureSharing.Data</RootNamespace> | |||
| </PropertyGroup> | |||
| <ItemGroup> | |||
| <PackageReference Include="AutoMapper" Version="11.0.1" /> | |||
| <PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="6.0.9" /> | |||
| <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.9" /> | |||
| <PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.9" /> | |||
| <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.9" /> | |||
| <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.9"> | |||
| <PrivateAssets>all</PrivateAssets> | |||
| <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | |||
| </PackageReference> | |||
| <PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.1" /> | |||
| <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" /> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <PackageReference Include="AutoMapper" Version="11.0.1"/> | |||
| <PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="6.0.9"/> | |||
| <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.9"/> | |||
| <PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.9"/> | |||
| <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.9"/> | |||
| <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.9"> | |||
| <PrivateAssets>all</PrivateAssets> | |||
| <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | |||
| </PackageReference> | |||
| <PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.1"/> | |||
| <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0"/> | |||
| </ItemGroup> | |||
| </Project> | |||
| @@ -1,21 +1,14 @@ | |||
| using System; | |||
| using Microsoft.AspNetCore.Hosting; | |||
| using Microsoft.AspNetCore.Identity; | |||
| using Microsoft.AspNetCore.Identity.UI; | |||
| using Microsoft.EntityFrameworkCore; | |||
| using Microsoft.Extensions.Configuration; | |||
| using Microsoft.Extensions.DependencyInjection; | |||
| using SecureSharing.Data.DbContexts; | |||
| using Microsoft.AspNetCore.Hosting; | |||
| using SecureSharing.Areas.Identity; | |||
| [assembly: HostingStartup(typeof(SecureSharing.Areas.Identity.IdentityHostingStartup))] | |||
| namespace SecureSharing.Areas.Identity | |||
| [assembly: HostingStartup(typeof(IdentityHostingStartup))] | |||
| namespace SecureSharing.Areas.Identity; | |||
| public sealed class IdentityHostingStartup : IHostingStartup | |||
| { | |||
| public class IdentityHostingStartup : IHostingStartup | |||
| public void Configure(IWebHostBuilder builder) | |||
| { | |||
| public void Configure(IWebHostBuilder builder) | |||
| { | |||
| builder.ConfigureServices((context, services) => { | |||
| }); | |||
| } | |||
| builder.ConfigureServices((context, services) => { }); | |||
| } | |||
| } | |||
| @@ -11,22 +11,22 @@ | |||
| <section> | |||
| <form id="account" method="post"> | |||
| <h4>Use a local account to log in.</h4> | |||
| <hr /> | |||
| <hr/> | |||
| <div asp-validation-summary="All" class="text-danger"></div> | |||
| <div class="form-group"> | |||
| <label asp-for="Input.Email"></label> | |||
| <input asp-for="Input.Email" class="form-control" /> | |||
| <input asp-for="Input.Email" class="form-control"/> | |||
| <span asp-validation-for="Input.Email" class="text-danger"></span> | |||
| </div> | |||
| <div class="form-group"> | |||
| <label asp-for="Input.Password"></label> | |||
| <input asp-for="Input.Password" class="form-control" /> | |||
| <input asp-for="Input.Password" class="form-control"/> | |||
| <span asp-validation-for="Input.Password" class="text-danger"></span> | |||
| </div> | |||
| <div class="form-group"> | |||
| <div class="checkbox"> | |||
| <label asp-for="Input.RememberMe"> | |||
| <input asp-for="Input.RememberMe" /> | |||
| <input asp-for="Input.RememberMe"/> | |||
| @Html.DisplayNameFor(m => m.Input.RememberMe) | |||
| </label> | |||
| </div> | |||
| @@ -51,7 +51,7 @@ | |||
| <div class="col-md-6 col-md-offset-2"> | |||
| <section> | |||
| <h4>Use another service to log in.</h4> | |||
| <hr /> | |||
| <hr/> | |||
| @{ | |||
| if ((Model.ExternalLogins?.Count ?? 0) == 0) | |||
| { | |||
| @@ -81,5 +81,5 @@ | |||
| </div> | |||
| @section Scripts { | |||
| <partial name="_ValidationScriptsPartial" /> | |||
| } | |||
| <partial name="_ValidationScriptsPartial"/> | |||
| } | |||
| @@ -1,110 +1,95 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Collections.Generic; | |||
| using System.ComponentModel.DataAnnotations; | |||
| using System.Linq; | |||
| using System.Text.Encodings.Web; | |||
| using System.Threading.Tasks; | |||
| using Microsoft.AspNetCore.Authorization; | |||
| using Microsoft.AspNetCore.Authentication; | |||
| using Microsoft.AspNetCore.Authorization; | |||
| using Microsoft.AspNetCore.Identity; | |||
| using Microsoft.AspNetCore.Identity.UI.Services; | |||
| using Microsoft.AspNetCore.Mvc; | |||
| using Microsoft.AspNetCore.Mvc.RazorPages; | |||
| using Microsoft.Extensions.Logging; | |||
| namespace SecureSharing.Areas.Identity.Pages.Account | |||
| { | |||
| [AllowAnonymous] | |||
| public class LoginModel : PageModel | |||
| { | |||
| private readonly UserManager<IdentityUser> _userManager; | |||
| private readonly SignInManager<IdentityUser> _signInManager; | |||
| private readonly ILogger<LoginModel> _logger; | |||
| namespace SecureSharing.Areas.Identity.Pages.Account; | |||
| public LoginModel(SignInManager<IdentityUser> signInManager, | |||
| ILogger<LoginModel> logger, | |||
| UserManager<IdentityUser> userManager) | |||
| { | |||
| _userManager = userManager; | |||
| _signInManager = signInManager; | |||
| _logger = logger; | |||
| } | |||
| [AllowAnonymous] | |||
| public sealed class LoginModel : PageModel | |||
| { | |||
| private readonly ILogger<LoginModel> _logger; | |||
| private readonly SignInManager<IdentityUser> _signInManager; | |||
| private readonly UserManager<IdentityUser> _userManager; | |||
| [BindProperty] | |||
| public InputModel Input { get; set; } | |||
| public LoginModel(SignInManager<IdentityUser> signInManager, | |||
| ILogger<LoginModel> logger, | |||
| UserManager<IdentityUser> userManager) | |||
| { | |||
| _userManager = userManager; | |||
| _signInManager = signInManager; | |||
| _logger = logger; | |||
| } | |||
| public IList<AuthenticationScheme> ExternalLogins { get; set; } | |||
| [BindProperty] public InputModel Input { get; set; } | |||
| public string ReturnUrl { get; set; } | |||
| public IList<AuthenticationScheme> ExternalLogins { get; set; } | |||
| [TempData] | |||
| public string ErrorMessage { get; set; } | |||
| public string ReturnUrl { get; set; } | |||
| public class InputModel | |||
| { | |||
| [Required] | |||
| [EmailAddress] | |||
| public string Email { get; set; } | |||
| [TempData] public string ErrorMessage { get; set; } | |||
| [Required] | |||
| [DataType(DataType.Password)] | |||
| public string Password { get; set; } | |||
| public async Task OnGetAsync(string returnUrl = null) | |||
| { | |||
| if (!string.IsNullOrEmpty(ErrorMessage)) ModelState.AddModelError(string.Empty, ErrorMessage); | |||
| [Display(Name = "Remember me?")] | |||
| public bool RememberMe { get; set; } | |||
| } | |||
| returnUrl ??= Url.Content("~/"); | |||
| public async Task OnGetAsync(string returnUrl = null) | |||
| { | |||
| if (!string.IsNullOrEmpty(ErrorMessage)) | |||
| { | |||
| ModelState.AddModelError(string.Empty, ErrorMessage); | |||
| } | |||
| // Clear the existing external cookie to ensure a clean login process | |||
| await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme); | |||
| returnUrl ??= Url.Content("~/"); | |||
| ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList(); | |||
| // Clear the existing external cookie to ensure a clean login process | |||
| await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme); | |||
| ReturnUrl = returnUrl; | |||
| } | |||
| ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList(); | |||
| public async Task<IActionResult> OnPostAsync(string returnUrl = null) | |||
| { | |||
| returnUrl ??= Url.Content("~/"); | |||
| ReturnUrl = returnUrl; | |||
| } | |||
| ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList(); | |||
| public async Task<IActionResult> OnPostAsync(string returnUrl = null) | |||
| if (ModelState.IsValid) | |||
| { | |||
| returnUrl ??= Url.Content("~/"); | |||
| // This doesn't count login failures towards account lockout | |||
| // To enable password failures to trigger account lockout, set lockoutOnFailure: true | |||
| var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, false); | |||
| if (result.Succeeded) | |||
| { | |||
| _logger.LogInformation("User logged in."); | |||
| return LocalRedirect(returnUrl); | |||
| } | |||
| ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList(); | |||
| if (ModelState.IsValid) | |||
| if (result.RequiresTwoFactor) | |||
| return RedirectToPage("./LoginWith2fa", new { ReturnUrl = returnUrl, Input.RememberMe }); | |||
| if (result.IsLockedOut) | |||
| { | |||
| // This doesn't count login failures towards account lockout | |||
| // To enable password failures to trigger account lockout, set lockoutOnFailure: true | |||
| var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: false); | |||
| if (result.Succeeded) | |||
| { | |||
| _logger.LogInformation("User logged in."); | |||
| return LocalRedirect(returnUrl); | |||
| } | |||
| if (result.RequiresTwoFactor) | |||
| { | |||
| return RedirectToPage("./LoginWith2fa", new { ReturnUrl = returnUrl, RememberMe = Input.RememberMe }); | |||
| } | |||
| if (result.IsLockedOut) | |||
| { | |||
| _logger.LogWarning("User account locked out."); | |||
| return RedirectToPage("./Lockout"); | |||
| } | |||
| else | |||
| { | |||
| ModelState.AddModelError(string.Empty, "Invalid login attempt."); | |||
| return Page(); | |||
| } | |||
| _logger.LogWarning("User account locked out."); | |||
| return RedirectToPage("./Lockout"); | |||
| } | |||
| // If we got this far, something failed, redisplay form | |||
| ModelState.AddModelError(string.Empty, "Invalid login attempt."); | |||
| return Page(); | |||
| } | |||
| // If we got this far, something failed, redisplay form | |||
| return Page(); | |||
| } | |||
| public sealed class InputModel | |||
| { | |||
| [Required] [EmailAddress] public string Email { get; set; } | |||
| [Required] | |||
| [DataType(DataType.Password)] | |||
| public string Password { get; set; } | |||
| [Display(Name = "Remember me?")] public bool RememberMe { get; set; } | |||
| } | |||
| } | |||
| } | |||
| @@ -10,21 +10,21 @@ | |||
| <div class="col-md-4"> | |||
| <form asp-route-returnUrl="@Model.ReturnUrl" method="post"> | |||
| <h4>Create a new account.</h4> | |||
| <hr /> | |||
| <hr/> | |||
| <div asp-validation-summary="All" class="text-danger"></div> | |||
| <div class="form-group"> | |||
| <label asp-for="Input.Email"></label> | |||
| <input asp-for="Input.Email" class="form-control" /> | |||
| <input asp-for="Input.Email" class="form-control"/> | |||
| <span asp-validation-for="Input.Email" class="text-danger"></span> | |||
| </div> | |||
| <div class="form-group"> | |||
| <label asp-for="Input.Password"></label> | |||
| <input asp-for="Input.Password" class="form-control" /> | |||
| <input asp-for="Input.Password" class="form-control"/> | |||
| <span asp-validation-for="Input.Password" class="text-danger"></span> | |||
| </div> | |||
| <div class="form-group"> | |||
| <label asp-for="Input.ConfirmPassword"></label> | |||
| <input asp-for="Input.ConfirmPassword" class="form-control" /> | |||
| <input asp-for="Input.ConfirmPassword" class="form-control"/> | |||
| <span asp-validation-for="Input.ConfirmPassword" class="text-danger"></span> | |||
| </div> | |||
| <button type="submit" class="btn btn-primary">Register</button> | |||
| @@ -33,7 +33,7 @@ | |||
| <div class="col-md-6 col-md-offset-2"> | |||
| <section> | |||
| <h4>Use another service to register.</h4> | |||
| <hr /> | |||
| <hr/> | |||
| @{ | |||
| if ((Model.ExternalLogins?.Count ?? 0) == 0) | |||
| { | |||
| @@ -63,5 +63,5 @@ | |||
| </div> | |||
| @section Scripts { | |||
| <partial name="_ValidationScriptsPartial" /> | |||
| } | |||
| <partial name="_ValidationScriptsPartial"/> | |||
| } | |||
| @@ -1,5 +1,4 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Collections.Generic; | |||
| using System.ComponentModel.DataAnnotations; | |||
| using System.Linq; | |||
| using System.Text; | |||
| @@ -14,101 +13,96 @@ using Microsoft.AspNetCore.Mvc.RazorPages; | |||
| using Microsoft.AspNetCore.WebUtilities; | |||
| using Microsoft.Extensions.Logging; | |||
| namespace SecureSharing.Areas.Identity.Pages.Account | |||
| namespace SecureSharing.Areas.Identity.Pages.Account; | |||
| [AllowAnonymous] | |||
| public sealed class RegisterModel : PageModel | |||
| { | |||
| [AllowAnonymous] | |||
| public class RegisterModel : PageModel | |||
| private readonly IEmailSender _emailSender; | |||
| private readonly ILogger<RegisterModel> _logger; | |||
| private readonly SignInManager<IdentityUser> _signInManager; | |||
| private readonly UserManager<IdentityUser> _userManager; | |||
| public RegisterModel( | |||
| UserManager<IdentityUser> userManager, | |||
| SignInManager<IdentityUser> signInManager, | |||
| ILogger<RegisterModel> logger, | |||
| IEmailSender emailSender) | |||
| { | |||
| private readonly SignInManager<IdentityUser> _signInManager; | |||
| private readonly UserManager<IdentityUser> _userManager; | |||
| private readonly ILogger<RegisterModel> _logger; | |||
| private readonly IEmailSender _emailSender; | |||
| public RegisterModel( | |||
| UserManager<IdentityUser> userManager, | |||
| SignInManager<IdentityUser> signInManager, | |||
| ILogger<RegisterModel> logger, | |||
| IEmailSender emailSender) | |||
| { | |||
| _userManager = userManager; | |||
| _signInManager = signInManager; | |||
| _logger = logger; | |||
| _emailSender = emailSender; | |||
| } | |||
| _userManager = userManager; | |||
| _signInManager = signInManager; | |||
| _logger = logger; | |||
| _emailSender = emailSender; | |||
| } | |||
| [BindProperty] | |||
| public InputModel Input { get; set; } | |||
| [BindProperty] public InputModel Input { get; set; } | |||
| public string ReturnUrl { get; set; } | |||
| public string ReturnUrl { get; set; } | |||
| public IList<AuthenticationScheme> ExternalLogins { get; set; } | |||
| public IList<AuthenticationScheme> ExternalLogins { get; set; } | |||
| public class InputModel | |||
| { | |||
| [Required] | |||
| [EmailAddress] | |||
| [Display(Name = "Email")] | |||
| public string Email { get; set; } | |||
| [Required] | |||
| [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)] | |||
| [DataType(DataType.Password)] | |||
| [Display(Name = "Password")] | |||
| public string Password { get; set; } | |||
| [DataType(DataType.Password)] | |||
| [Display(Name = "Confirm password")] | |||
| [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] | |||
| public string ConfirmPassword { get; set; } | |||
| } | |||
| public async Task OnGetAsync(string returnUrl = null) | |||
| { | |||
| ReturnUrl = returnUrl; | |||
| ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList(); | |||
| } | |||
| public async Task OnGetAsync(string returnUrl = null) | |||
| { | |||
| ReturnUrl = returnUrl; | |||
| ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList(); | |||
| } | |||
| public async Task<IActionResult> OnPostAsync(string returnUrl = null) | |||
| public async Task<IActionResult> OnPostAsync(string returnUrl = null) | |||
| { | |||
| returnUrl ??= Url.Content("~/"); | |||
| ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList(); | |||
| if (ModelState.IsValid) | |||
| { | |||
| returnUrl ??= Url.Content("~/"); | |||
| ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList(); | |||
| if (ModelState.IsValid) | |||
| var user = new IdentityUser { UserName = Input.Email, Email = Input.Email }; | |||
| var result = await _userManager.CreateAsync(user, Input.Password); | |||
| if (result.Succeeded) | |||
| { | |||
| var user = new IdentityUser { UserName = Input.Email, Email = Input.Email }; | |||
| var result = await _userManager.CreateAsync(user, Input.Password); | |||
| if (result.Succeeded) | |||
| { | |||
| _logger.LogInformation("User created a new account with password."); | |||
| var code = await _userManager.GenerateEmailConfirmationTokenAsync(user); | |||
| code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code)); | |||
| var callbackUrl = Url.Page( | |||
| "/Account/ConfirmEmail", | |||
| pageHandler: null, | |||
| values: new { area = "Identity", userId = user.Id, code = code, returnUrl = returnUrl }, | |||
| protocol: Request.Scheme); | |||
| await _emailSender.SendEmailAsync(Input.Email, "Confirm your email", | |||
| $"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>."); | |||
| if (_userManager.Options.SignIn.RequireConfirmedAccount) | |||
| { | |||
| return RedirectToPage("RegisterConfirmation", new { email = Input.Email, returnUrl = returnUrl }); | |||
| } | |||
| else | |||
| { | |||
| await _signInManager.SignInAsync(user, isPersistent: false); | |||
| return LocalRedirect(returnUrl); | |||
| } | |||
| } | |||
| foreach (var error in result.Errors) | |||
| _logger.LogInformation("User created a new account with password."); | |||
| var code = await _userManager.GenerateEmailConfirmationTokenAsync(user); | |||
| code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code)); | |||
| var callbackUrl = Url.Page( | |||
| "/Account/ConfirmEmail", | |||
| null, | |||
| new { area = "Identity", userId = user.Id, code, returnUrl }, | |||
| Request.Scheme); | |||
| await _emailSender.SendEmailAsync(Input.Email, "Confirm your email", | |||
| $"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>."); | |||
| if (_userManager.Options.SignIn.RequireConfirmedAccount) | |||
| { | |||
| ModelState.AddModelError(string.Empty, error.Description); | |||
| return RedirectToPage("RegisterConfirmation", new { email = Input.Email, returnUrl }); | |||
| } | |||
| await _signInManager.SignInAsync(user, false); | |||
| return LocalRedirect(returnUrl); | |||
| } | |||
| // If we got this far, something failed, redisplay form | |||
| return Page(); | |||
| foreach (var error in result.Errors) ModelState.AddModelError(string.Empty, error.Description); | |||
| } | |||
| // If we got this far, something failed, redisplay form | |||
| return Page(); | |||
| } | |||
| public sealed class InputModel | |||
| { | |||
| [Required] | |||
| [EmailAddress] | |||
| [Display(Name = "Email")] | |||
| public string Email { get; set; } | |||
| [Required] | |||
| [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", | |||
| MinimumLength = 6)] | |||
| [DataType(DataType.Password)] | |||
| [Display(Name = "Password")] | |||
| public string Password { get; set; } | |||
| [DataType(DataType.Password)] | |||
| [Display(Name = "Confirm password")] | |||
| [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] | |||
| public string ConfirmPassword { get; set; } | |||
| } | |||
| } | |||
| } | |||
| @@ -6,25 +6,25 @@ | |||
| <h1>@ViewData["Title"]</h1> | |||
| <h4>Reset your password.</h4> | |||
| <hr /> | |||
| <hr/> | |||
| <div class="row"> | |||
| <div class="col-md-4"> | |||
| <form method="post"> | |||
| <div asp-validation-summary="ModelOnly" class="text-danger"></div> | |||
| <input asp-for="Input.Code" type="hidden" /> | |||
| <input asp-for="Input.Code" type="hidden"/> | |||
| <div class="form-group"> | |||
| <label asp-for="Input.Email"></label> | |||
| <input asp-for="Input.Email" class="form-control" /> | |||
| <input asp-for="Input.Email" class="form-control"/> | |||
| <span asp-validation-for="Input.Email" class="text-danger"></span> | |||
| </div> | |||
| <div class="form-group"> | |||
| <label asp-for="Input.Password"></label> | |||
| <input asp-for="Input.Password" class="form-control" /> | |||
| <input asp-for="Input.Password" class="form-control"/> | |||
| <span asp-validation-for="Input.Password" class="text-danger"></span> | |||
| </div> | |||
| <div class="form-group"> | |||
| <label asp-for="Input.ConfirmPassword"></label> | |||
| <input asp-for="Input.ConfirmPassword" class="form-control" /> | |||
| <input asp-for="Input.ConfirmPassword" class="form-control"/> | |||
| <span asp-validation-for="Input.ConfirmPassword" class="text-danger"></span> | |||
| </div> | |||
| <button type="submit" class="btn btn-primary">Reset</button> | |||
| @@ -33,5 +33,5 @@ | |||
| </div> | |||
| @section Scripts { | |||
| <partial name="_ValidationScriptsPartial" /> | |||
| } | |||
| <partial name="_ValidationScriptsPartial"/> | |||
| } | |||
| @@ -1,91 +1,69 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.ComponentModel.DataAnnotations; | |||
| using System.Linq; | |||
| using System.Text; | |||
| using System.ComponentModel.DataAnnotations; | |||
| using System.Threading.Tasks; | |||
| using System.Web; | |||
| using Microsoft.AspNetCore.Authorization; | |||
| using Microsoft.AspNetCore.Identity; | |||
| using Microsoft.AspNetCore.Mvc; | |||
| using Microsoft.AspNetCore.Mvc.RazorPages; | |||
| using Microsoft.AspNetCore.WebUtilities; | |||
| namespace SecureSharing.Areas.Identity.Pages.Account | |||
| namespace SecureSharing.Areas.Identity.Pages.Account; | |||
| [AllowAnonymous] | |||
| public sealed class ResetPasswordModel : PageModel | |||
| { | |||
| [AllowAnonymous] | |||
| public class ResetPasswordModel : PageModel | |||
| private readonly UserManager<IdentityUser> _userManager; | |||
| public ResetPasswordModel(UserManager<IdentityUser> userManager) | |||
| { | |||
| private readonly UserManager<IdentityUser> _userManager; | |||
| _userManager = userManager; | |||
| } | |||
| [BindProperty] public InputModel Input { get; set; } | |||
| public ResetPasswordModel(UserManager<IdentityUser> userManager) | |||
| public IActionResult OnGet(string code = null) | |||
| { | |||
| if (code == null) | |||
| { | |||
| _userManager = userManager; | |||
| return BadRequest("A code must be supplied for password reset."); | |||
| } | |||
| [BindProperty] | |||
| public InputModel Input { get; set; } | |||
| public class InputModel | |||
| Input = new InputModel | |||
| { | |||
| [Required] | |||
| [EmailAddress] | |||
| public string Email { get; set; } | |||
| Code = code | |||
| }; | |||
| return Page(); | |||
| } | |||
| [Required] | |||
| [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)] | |||
| [DataType(DataType.Password)] | |||
| public string Password { get; set; } | |||
| public async Task<IActionResult> OnPostAsync() | |||
| { | |||
| if (!ModelState.IsValid) return Page(); | |||
| [DataType(DataType.Password)] | |||
| [Display(Name = "Confirm password")] | |||
| [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] | |||
| public string ConfirmPassword { get; set; } | |||
| var user = await _userManager.FindByEmailAsync(Input.Email); | |||
| if (user == null) | |||
| // Don't reveal that the user does not exist | |||
| return RedirectToPage("./ResetPasswordConfirmation"); | |||
| public string Code { get; set; } | |||
| } | |||
| var result = await _userManager.ResetPasswordAsync(user, Input.Code, Input.Password); | |||
| if (result.Succeeded) return RedirectToPage("./ResetPasswordConfirmation"); | |||
| public IActionResult OnGet(string code = null) | |||
| { | |||
| if (code == null) | |||
| { | |||
| return BadRequest("A code must be supplied for password reset."); | |||
| } | |||
| else | |||
| { | |||
| Input = new InputModel | |||
| { | |||
| Code = code | |||
| }; | |||
| return Page(); | |||
| } | |||
| } | |||
| foreach (var error in result.Errors) ModelState.AddModelError(string.Empty, error.Description); | |||
| return Page(); | |||
| } | |||
| public async Task<IActionResult> OnPostAsync() | |||
| { | |||
| if (!ModelState.IsValid) | |||
| { | |||
| return Page(); | |||
| } | |||
| public sealed class InputModel | |||
| { | |||
| [Required] [EmailAddress] public string Email { get; set; } | |||
| var user = await _userManager.FindByEmailAsync(Input.Email); | |||
| if (user == null) | |||
| { | |||
| // Don't reveal that the user does not exist | |||
| return RedirectToPage("./ResetPasswordConfirmation"); | |||
| } | |||
| [Required] | |||
| [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", | |||
| MinimumLength = 6)] | |||
| [DataType(DataType.Password)] | |||
| public string Password { get; set; } | |||
| var result = await _userManager.ResetPasswordAsync(user, Input.Code, Input.Password); | |||
| if (result.Succeeded) | |||
| { | |||
| return RedirectToPage("./ResetPasswordConfirmation"); | |||
| } | |||
| [DataType(DataType.Password)] | |||
| [Display(Name = "Confirm password")] | |||
| [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] | |||
| public string ConfirmPassword { get; set; } | |||
| foreach (var error in result.Errors) | |||
| { | |||
| ModelState.AddModelError(string.Empty, error.Description); | |||
| } | |||
| return Page(); | |||
| } | |||
| public string Code { get; set; } | |||
| } | |||
| } | |||
| } | |||
| @@ -15,4 +15,4 @@ | |||
| crossorigin="anonymous" | |||
| integrity="sha384-ifv0TYDWxBHzvAk2Z0n8R434FL1Rlv/Av18DXE43N/1rvHyOG4izKst0f2iSLdds"> | |||
| </script> | |||
| </environment> | |||
| </environment> | |||
| @@ -1,4 +1,4 @@ | |||
| @using Microsoft.AspNetCore.Identity | |||
| @using SecureSharing.Areas.Identity | |||
| @using SecureSharing.Areas.Identity.Pages | |||
| @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers | |||
| @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers | |||
| @@ -1,4 +1,3 @@ | |||
| | |||
| @{ | |||
| @{ | |||
| Layout = "/Views/Shared/_Layout.cshtml"; | |||
| } | |||
| } | |||
| @@ -1,63 +1,53 @@ | |||
| using Microsoft.AspNetCore.Authorization; | |||
| using System.Threading.Tasks; | |||
| using Microsoft.AspNetCore.Authorization; | |||
| using Microsoft.AspNetCore.Mvc; | |||
| using Microsoft.Extensions.Logging; | |||
| using Newtonsoft.Json; | |||
| using SecureSharing.Business.Dtos; | |||
| using SecureSharing.Models; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Diagnostics; | |||
| using System.Linq; | |||
| using System.Threading.Tasks; | |||
| using SecureSharing.Business.Interfaces; | |||
| using SecureSharing.Infrastructure; | |||
| using SecureSharing.Models; | |||
| namespace SecureSharing.Controllers; | |||
| namespace SecureSharing.Controllers | |||
| [Authorize] | |||
| public sealed class HomeController : Controller | |||
| { | |||
| [Authorize] | |||
| public class HomeController : Controller | |||
| private readonly ILogger<HomeController> _logger; | |||
| private readonly IMessageService _messageService; | |||
| private readonly IModelFactory _modelFactory; | |||
| public HomeController(ILogger<HomeController> logger, IMessageService messageService, IModelFactory modelFactory) | |||
| { | |||
| _logger = logger; | |||
| _messageService = messageService; | |||
| _modelFactory = modelFactory; | |||
| } | |||
| public IActionResult Index() | |||
| { | |||
| return View(); | |||
| } | |||
| [HttpPost] | |||
| public async Task<IActionResult> CreateMessage(MessageModel model) | |||
| { | |||
| var message = new MessageDto { Text = model.Text }; | |||
| var id = await _messageService.Create(message, model.ChosenPeriod); | |||
| return RedirectToAction("Link", "Home", new { id, share = true }); | |||
| } | |||
| [HttpGet] | |||
| public async Task<IActionResult> Link(int id, bool? share) | |||
| { | |||
| var model = await _modelFactory.PrepareLinkVM(id, share); | |||
| return View(model); | |||
| } | |||
| public IActionResult Privacy() | |||
| { | |||
| private readonly ILogger<HomeController> _logger; | |||
| private readonly IMessageService _messageService; | |||
| private readonly IModelFactory _modelFactory; | |||
| public HomeController(ILogger<HomeController> logger, IMessageService messageService, IModelFactory modelFactory) | |||
| { | |||
| _logger = logger; | |||
| _messageService = messageService; | |||
| _modelFactory = modelFactory; | |||
| } | |||
| public IActionResult Index() | |||
| { | |||
| return View(); | |||
| } | |||
| [HttpPost] | |||
| public async Task<IActionResult> CreateMessage(MessageModel model) | |||
| { | |||
| MessageDto message = new MessageDto { Text = model.Text}; | |||
| int id = await _messageService.Create(message, model.ChosenPeriod); | |||
| return RedirectToAction("Link", "Home", new { id = id, share = true }); | |||
| } | |||
| [HttpGet] | |||
| public async Task<IActionResult> Link(int id, bool? share) | |||
| { | |||
| var model = await _modelFactory.PrepareLinkVM(id, share); | |||
| return View(model); | |||
| } | |||
| public IActionResult Privacy() | |||
| { | |||
| return View(); | |||
| } | |||
| return View(); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,12 +1,10 @@ | |||
| using SecureSharing.Business.Dtos; | |||
| using System.Threading.Tasks; | |||
| using SecureSharing.Models; | |||
| using System.Threading.Tasks; | |||
| namespace SecureSharing.Infrastructure | |||
| namespace SecureSharing.Infrastructure; | |||
| public interface IModelFactory | |||
| { | |||
| public interface IModelFactory | |||
| { | |||
| //public MessageModel PrepareMessageVM(MessageDto message); | |||
| public Task<LinkModel> PrepareLinkVM(int id, bool? share); | |||
| } | |||
| } | |||
| //public MessageModel PrepareMessageVM(MessageDto message); | |||
| public Task<LinkModel> PrepareLinkVM(int id, bool? share); | |||
| } | |||
| @@ -1,66 +1,64 @@ | |||
| using Microsoft.AspNetCore.Hosting; | |||
| using Microsoft.AspNetCore.Http; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| using System; | |||
| using System.Net; | |||
| using System.Threading.Tasks; | |||
| using Microsoft.AspNetCore.Hosting; | |||
| using Microsoft.AspNetCore.Http; | |||
| using Newtonsoft.Json; | |||
| using Serilog; | |||
| namespace SecureSharing.Infrastructure.Middleware | |||
| { | |||
| public class ExceptionHandlingMiddleware | |||
| { | |||
| private RequestDelegate nextRequestDelegate; | |||
| private IWebHostEnvironment environment; | |||
| namespace SecureSharing.Infrastructure.Middleware; | |||
| public ExceptionHandlingMiddleware( | |||
| RequestDelegate nextRequestDelegate, | |||
| IWebHostEnvironment environment | |||
| ) | |||
| { | |||
| this.nextRequestDelegate = nextRequestDelegate ?? throw new ArgumentNullException(nameof(nextRequestDelegate)); | |||
| this.environment = environment ?? throw new ArgumentNullException(nameof(environment)); | |||
| } | |||
| public sealed class ExceptionHandlingMiddleware | |||
| { | |||
| private IWebHostEnvironment environment; | |||
| private readonly RequestDelegate nextRequestDelegate; | |||
| public async Task Invoke(HttpContext context) | |||
| { | |||
| try | |||
| { | |||
| context.TraceIdentifier = Guid.NewGuid().ToString(); | |||
| await this.nextRequestDelegate(context); | |||
| } | |||
| catch (Exception ex) | |||
| { | |||
| await this.HandleGlobalExceptionAsync(context, ex); | |||
| } | |||
| } | |||
| public ExceptionHandlingMiddleware( | |||
| RequestDelegate nextRequestDelegate, | |||
| IWebHostEnvironment environment | |||
| ) | |||
| { | |||
| this.nextRequestDelegate = nextRequestDelegate ?? throw new ArgumentNullException(nameof(nextRequestDelegate)); | |||
| this.environment = environment ?? throw new ArgumentNullException(nameof(environment)); | |||
| } | |||
| private async Task HandleGlobalExceptionAsync(HttpContext context, Exception ex) | |||
| { | |||
| public async Task Invoke(HttpContext context) | |||
| { | |||
| try | |||
| { | |||
| context.TraceIdentifier = Guid.NewGuid().ToString(); | |||
| await nextRequestDelegate(context); | |||
| } | |||
| catch (Exception ex) | |||
| { | |||
| await HandleGlobalExceptionAsync(context, ex); | |||
| } | |||
| } | |||
| try | |||
| { | |||
| await this.WriteResponseAsync(context, HttpStatusCode.InternalServerError, JsonConvert.SerializeObject(ex.Message)); | |||
| } | |||
| catch (Exception e) | |||
| { | |||
| await this.WriteResponseAsync(context, HttpStatusCode.InternalServerError, JsonConvert.SerializeObject(e.Message)); | |||
| } | |||
| private async Task HandleGlobalExceptionAsync(HttpContext context, Exception ex) | |||
| { | |||
| try | |||
| { | |||
| await WriteResponseAsync(context, HttpStatusCode.InternalServerError, | |||
| JsonConvert.SerializeObject(ex.Message)); | |||
| } | |||
| catch (Exception e) | |||
| { | |||
| await WriteResponseAsync(context, HttpStatusCode.InternalServerError, | |||
| JsonConvert.SerializeObject(e.Message)); | |||
| } | |||
| var logger = new LoggerConfiguration() | |||
| .MinimumLevel.Debug() | |||
| .WriteTo.File(@"AppData\Errors\log-.log", rollingInterval: RollingInterval.Day) | |||
| .CreateLogger(); | |||
| logger.Error(ex, "Unhandled Exception"/* - Detected UserId: {UserId}" /*, context.User.GetUserId()*/); | |||
| } | |||
| var logger = new LoggerConfiguration() | |||
| .MinimumLevel.Debug() | |||
| .WriteTo.File(@"AppData\Errors\log-.log", rollingInterval: RollingInterval.Day) | |||
| .CreateLogger(); | |||
| logger.Error(ex, "Unhandled Exception" /* - Detected UserId: {UserId}" /*, context.User.GetUserId()*/); | |||
| } | |||
| private async Task WriteResponseAsync(HttpContext context, HttpStatusCode code, string jsonResponse) | |||
| { | |||
| context.Response.ContentType = "application/json"; | |||
| context.Response.StatusCode = (int)code; | |||
| await context.Response.WriteAsync(jsonResponse); | |||
| } | |||
| } | |||
| } | |||
| private async Task WriteResponseAsync(HttpContext context, HttpStatusCode code, string jsonResponse) | |||
| { | |||
| context.Response.ContentType = "application/json"; | |||
| context.Response.StatusCode = (int)code; | |||
| await context.Response.WriteAsync(jsonResponse); | |||
| } | |||
| } | |||
| @@ -1,65 +1,59 @@ | |||
| using SecureSharing.Business.Dtos; | |||
| using System; | |||
| using System.Threading.Tasks; | |||
| using SecureSharing.Business.Interfaces; | |||
| using SecureSharing.Models; | |||
| using System; | |||
| using System.Threading.Tasks; | |||
| namespace SecureSharing.Infrastructure | |||
| namespace SecureSharing.Infrastructure; | |||
| public sealed class ModelFactory : IModelFactory | |||
| { | |||
| public class ModelFactory : IModelFactory | |||
| private readonly IMessageService _messageService; | |||
| public ModelFactory(IMessageService messageService) | |||
| { | |||
| _messageService = messageService; | |||
| } | |||
| private readonly IMessageService _messageService; | |||
| public async Task<LinkModel> PrepareLinkVM(int id, bool? share) | |||
| { | |||
| //share is true when the link is created | |||
| public ModelFactory(IMessageService messageService) | |||
| LinkModel model = null; | |||
| try | |||
| { | |||
| _messageService = messageService; | |||
| } | |||
| var message = await _messageService.GetById(id); | |||
| public async Task<LinkModel> PrepareLinkVM(int id, bool? share) | |||
| { | |||
| //share is true when the link is created | |||
| model = new LinkModel { message = new MessageModel { Id = id, Text = message.Text }, Share = share }; | |||
| model.IsValid = message.IsValid; | |||
| LinkModel model = null; | |||
| try | |||
| if (model.IsValid) | |||
| { | |||
| MessageDto message = await _messageService.GetById(id); | |||
| model = new LinkModel { message = new MessageModel { Id = id, Text = message.Text }, Share = share }; | |||
| model.IsValid = message.IsValid; | |||
| if (model.IsValid) | |||
| if (message.ExpiryDate != null) | |||
| { | |||
| if (message.ExpiryDate != null) | |||
| model.TimeLeft = message.ExpiryDate - DateTime.UtcNow; | |||
| if (message.ExpiryDate <= DateTime.UtcNow) | |||
| { | |||
| model.TimeLeft = message.ExpiryDate - DateTime.UtcNow; | |||
| if (message.ExpiryDate <= DateTime.UtcNow) | |||
| { | |||
| await _messageService.InvalidateMessage(message.Id); | |||
| model.IsValid = false; | |||
| } | |||
| } | |||
| else | |||
| { | |||
| //ONE_TIME sharing: make the message invalid now so that it can't be accessed next time | |||
| if (share == null || share.Value == false) | |||
| { | |||
| await _messageService.InvalidateMessage(message.Id); | |||
| } | |||
| await _messageService.InvalidateMessage(message.Id); | |||
| model.IsValid = false; | |||
| } | |||
| } | |||
| else | |||
| { | |||
| //ONE_TIME sharing: make the message invalid now so that it can't be accessed next time | |||
| if (share == null || share.Value == false) await _messageService.InvalidateMessage(message.Id); | |||
| } | |||
| } | |||
| catch (Exception e) | |||
| { | |||
| model = new LinkModel { IsValid = false }; | |||
| } | |||
| return model; | |||
| } | |||
| catch (Exception e) | |||
| { | |||
| model = new LinkModel { IsValid = false }; | |||
| } | |||
| //public MessageModel PrepareMessageVM(MessageDto message) | |||
| //{ | |||
| // throw new System.NotImplementedException(); | |||
| //} | |||
| return model; | |||
| } | |||
| } | |||
| //public MessageModel PrepareMessageVM(MessageDto message) | |||
| //{ | |||
| // throw new System.NotImplementedException(); | |||
| //} | |||
| } | |||
| @@ -1,11 +1,8 @@ | |||
| using System; | |||
| namespace SecureSharing.Models; | |||
| namespace SecureSharing.Models | |||
| public sealed class ErrorViewModel | |||
| { | |||
| public class ErrorViewModel | |||
| { | |||
| public string RequestId { get; set; } | |||
| public string RequestId { get; set; } | |||
| public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); | |||
| } | |||
| } | |||
| public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); | |||
| } | |||
| @@ -1,14 +1,13 @@ | |||
| using System; | |||
| namespace SecureSharing.Models | |||
| namespace SecureSharing.Models; | |||
| public sealed class LinkModel | |||
| { | |||
| public class LinkModel | |||
| { | |||
| public string Link { get; set; } | |||
| public MessageModel message { get; set; } | |||
| public bool? Share { get; set; } | |||
| public TimeSpan? TimeLeft { get; set; } | |||
| public string Link { get; set; } | |||
| public MessageModel message { get; set; } | |||
| public bool? Share { get; set; } | |||
| public TimeSpan? TimeLeft { get; set; } | |||
| public bool IsValid { get; set; } | |||
| } | |||
| } | |||
| public bool IsValid { get; set; } | |||
| } | |||
| @@ -1,19 +1,12 @@ | |||
| using SecureSharing.Business.Infrastructure; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| namespace SecureSharing.Models | |||
| { | |||
| public class MessageModel | |||
| { | |||
| public int Id { get; set; } | |||
| public string Text { get; set; } | |||
| public PeriodOfValidity ChosenPeriod { get; set; } | |||
| // public Dictionary<int, string> AvailablePeriods { get; set; } | |||
| namespace SecureSharing.Models; | |||
| public sealed class MessageModel | |||
| { | |||
| public int Id { get; set; } | |||
| public string Text { get; set; } | |||
| public PeriodOfValidity ChosenPeriod { get; set; } | |||
| } | |||
| } | |||
| // public Dictionary<int, string> AvailablePeriods { get; set; } | |||
| } | |||
| @@ -1,26 +1,18 @@ | |||
| using Microsoft.AspNetCore.Hosting; | |||
| using Microsoft.Extensions.Configuration; | |||
| using Microsoft.Extensions.Hosting; | |||
| using Microsoft.Extensions.Logging; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| using System.Threading.Tasks; | |||
| namespace SecureSharing | |||
| namespace SecureSharing; | |||
| public sealed class Program | |||
| { | |||
| public class Program | |||
| public static void Main(string[] args) | |||
| { | |||
| public static void Main(string[] args) | |||
| { | |||
| CreateHostBuilder(args).Build().Run(); | |||
| } | |||
| CreateHostBuilder(args).Build().Run(); | |||
| } | |||
| public static IHostBuilder CreateHostBuilder(string[] args) => | |||
| Host.CreateDefaultBuilder(args) | |||
| .ConfigureWebHostDefaults(webBuilder => | |||
| { | |||
| webBuilder.UseStartup<Startup>(); | |||
| }); | |||
| public static IHostBuilder CreateHostBuilder(string[] args) | |||
| { | |||
| return Host.CreateDefaultBuilder(args) | |||
| .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }); | |||
| } | |||
| } | |||
| } | |||
| @@ -3,14 +3,14 @@ | |||
| https://go.microsoft.com/fwlink/?LinkID=208121. | |||
| --> | |||
| <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||
| <PropertyGroup> | |||
| <DeleteExistingFiles>False</DeleteExistingFiles> | |||
| <ExcludeApp_Data>False</ExcludeApp_Data> | |||
| <LaunchSiteAfterPublish>True</LaunchSiteAfterPublish> | |||
| <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration> | |||
| <LastUsedPlatform>Any CPU</LastUsedPlatform> | |||
| <PublishProvider>FileSystem</PublishProvider> | |||
| <PublishUrl>D:\Publish\ScreeningTestApp</PublishUrl> | |||
| <WebPublishMethod>FileSystem</WebPublishMethod> | |||
| </PropertyGroup> | |||
| <PropertyGroup> | |||
| <DeleteExistingFiles>False</DeleteExistingFiles> | |||
| <ExcludeApp_Data>False</ExcludeApp_Data> | |||
| <LaunchSiteAfterPublish>True</LaunchSiteAfterPublish> | |||
| <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration> | |||
| <LastUsedPlatform>Any CPU</LastUsedPlatform> | |||
| <PublishProvider>FileSystem</PublishProvider> | |||
| <PublishUrl>D:\Publish\ScreeningTestApp</PublishUrl> | |||
| <WebPublishMethod>FileSystem</WebPublishMethod> | |||
| </PropertyGroup> | |||
| </Project> | |||
| @@ -4,22 +4,22 @@ This file is used by the publish/package process of your Web project. You can cu | |||
| by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121. | |||
| --> | |||
| <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||
| <PropertyGroup> | |||
| <WebPublishMethod>MSDeploy</WebPublishMethod> | |||
| <LaunchSiteAfterPublish>True</LaunchSiteAfterPublish> | |||
| <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration> | |||
| <LastUsedPlatform>Any CPU</LastUsedPlatform> | |||
| <SiteUrlToLaunchAfterPublish /> | |||
| <ExcludeApp_Data>False</ExcludeApp_Data> | |||
| <ProjectGuid>495fb586-0b0f-4368-87a3-c13444149d2a</ProjectGuid> | |||
| <SelfContained>false</SelfContained> | |||
| <MSDeployServiceURL>dg00</MSDeployServiceURL> | |||
| <DeployIisAppPath>ScreeningTestApp</DeployIisAppPath> | |||
| <RemoteSitePhysicalPath /> | |||
| <SkipExtraFilesOnServer>True</SkipExtraFilesOnServer> | |||
| <MSDeployPublishMethod>WMSVC</MSDeployPublishMethod> | |||
| <EnableMSDeployBackup>True</EnableMSDeployBackup> | |||
| <UserName>nenad.stojanovic@dilig.net</UserName> | |||
| <_SavePWD>True</_SavePWD> | |||
| </PropertyGroup> | |||
| <PropertyGroup> | |||
| <WebPublishMethod>MSDeploy</WebPublishMethod> | |||
| <LaunchSiteAfterPublish>True</LaunchSiteAfterPublish> | |||
| <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration> | |||
| <LastUsedPlatform>Any CPU</LastUsedPlatform> | |||
| <SiteUrlToLaunchAfterPublish/> | |||
| <ExcludeApp_Data>False</ExcludeApp_Data> | |||
| <ProjectGuid>495fb586-0b0f-4368-87a3-c13444149d2a</ProjectGuid> | |||
| <SelfContained>false</SelfContained> | |||
| <MSDeployServiceURL>dg00</MSDeployServiceURL> | |||
| <DeployIisAppPath>ScreeningTestApp</DeployIisAppPath> | |||
| <RemoteSitePhysicalPath/> | |||
| <SkipExtraFilesOnServer>True</SkipExtraFilesOnServer> | |||
| <MSDeployPublishMethod>WMSVC</MSDeployPublishMethod> | |||
| <EnableMSDeployBackup>True</EnableMSDeployBackup> | |||
| <UserName>nenad.stojanovic@dilig.net</UserName> | |||
| <_SavePWD>True</_SavePWD> | |||
| </PropertyGroup> | |||
| </Project> | |||
| @@ -1,57 +1,53 @@ | |||
| using Microsoft.Extensions.DependencyInjection; | |||
| using System; | |||
| using System.Collections.Concurrent; | |||
| using Microsoft.Extensions.DependencyInjection; | |||
| using Quartz; | |||
| using Quartz.Spi; | |||
| using System; | |||
| using System.Collections.Concurrent; | |||
| namespace SecureSharing.Quartz | |||
| namespace SecureSharing.Quartz; | |||
| public class JobFactory : IJobFactory | |||
| { | |||
| public class JobFactory : IJobFactory | |||
| protected readonly ConcurrentDictionary<IJob, IServiceScope> _scopes = new(); | |||
| protected readonly IServiceProvider _serviceProvider; | |||
| public JobFactory(IServiceProvider serviceProvider) | |||
| { | |||
| protected readonly IServiceProvider _serviceProvider; | |||
| _serviceProvider = serviceProvider; | |||
| } | |||
| protected readonly ConcurrentDictionary<IJob, IServiceScope> _scopes = new ConcurrentDictionary<IJob, IServiceScope>(); | |||
| public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler) | |||
| { | |||
| var scope = _serviceProvider.CreateScope(); | |||
| IJob job; | |||
| public JobFactory(IServiceProvider serviceProvider) | |||
| try | |||
| { | |||
| _serviceProvider = serviceProvider; | |||
| job = scope.ServiceProvider.GetRequiredService(bundle.JobDetail.JobType) as IJob; | |||
| } | |||
| public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler) | |||
| catch | |||
| { | |||
| var scope = _serviceProvider.CreateScope(); | |||
| IJob job; | |||
| try | |||
| { | |||
| job = scope.ServiceProvider.GetRequiredService(bundle.JobDetail.JobType) as IJob; | |||
| } | |||
| catch | |||
| { | |||
| // Failed to create the job -> ensure scope gets disposed | |||
| scope.Dispose(); | |||
| throw; | |||
| } | |||
| // Add scope to dictionary so we can dispose it once the job finishes | |||
| if (!_scopes.TryAdd(job, scope)) | |||
| { | |||
| // Failed to track DI scope -> ensure scope gets disposed | |||
| scope.Dispose(); | |||
| throw new Exception("Failed to track DI scope"); | |||
| } | |||
| return job; | |||
| // Failed to create the job -> ensure scope gets disposed | |||
| scope.Dispose(); | |||
| throw; | |||
| } | |||
| public void ReturnJob(IJob job) | |||
| // Add scope to dictionary so we can dispose it once the job finishes | |||
| if (!_scopes.TryAdd(job, scope)) | |||
| { | |||
| if (_scopes.TryRemove(job, out var scope)) | |||
| { | |||
| // The Dispose() method ends the scope lifetime. | |||
| // Once Dispose is called, any scoped services that have been resolved from ServiceProvider will be disposed. | |||
| scope.Dispose(); | |||
| } | |||
| // Failed to track DI scope -> ensure scope gets disposed | |||
| scope.Dispose(); | |||
| throw new Exception("Failed to track DI scope"); | |||
| } | |||
| return job; | |||
| } | |||
| public void ReturnJob(IJob job) | |||
| { | |||
| if (_scopes.TryRemove(job, out var scope)) | |||
| // The Dispose() method ends the scope lifetime. | |||
| // Once Dispose is called, any scoped services that have been resolved from ServiceProvider will be disposed. | |||
| scope.Dispose(); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,20 +1,20 @@ | |||
| using System; | |||
| namespace SecureSharing.Quartz | |||
| namespace SecureSharing.Quartz; | |||
| public sealed class JobMetadata | |||
| { | |||
| public class JobMetadata | |||
| { | |||
| public Guid JobId { get; set; } | |||
| public Type JobType { get; } | |||
| public string JobName { get; } | |||
| public string CronExpression { get; } | |||
| public JobMetadata(Type jobType, | |||
| public JobMetadata(Type jobType, | |||
| string cronExpression) | |||
| { | |||
| //JobId = Id; | |||
| JobType = jobType; | |||
| //JobName = jobName; | |||
| CronExpression = cronExpression; | |||
| } | |||
| { | |||
| //JobId = Id; | |||
| JobType = jobType; | |||
| //JobName = jobName; | |||
| CronExpression = cronExpression; | |||
| } | |||
| } | |||
| public Guid JobId { get; set; } | |||
| public Type JobType { get; } | |||
| public string JobName { get; } | |||
| public string CronExpression { get; } | |||
| } | |||
| @@ -1,54 +1,59 @@ | |||
| using Microsoft.Extensions.Hosting; | |||
| using System.Threading; | |||
| using System.Threading.Tasks; | |||
| using Microsoft.Extensions.Hosting; | |||
| using Quartz; | |||
| using Quartz.Spi; | |||
| using System.Threading; | |||
| using System.Threading.Tasks; | |||
| namespace SecureSharing.Quartz | |||
| namespace SecureSharing.Quartz; | |||
| public sealed class JobsService : IHostedService | |||
| { | |||
| public class JobsService: IHostedService | |||
| { | |||
| private readonly ISchedulerFactory schedulerFactory; | |||
| private readonly IJobFactory jobFactory; | |||
| private readonly JobMetadata jobMetadata; | |||
| public JobsService(ISchedulerFactory | |||
| private readonly IJobFactory jobFactory; | |||
| private readonly JobMetadata jobMetadata; | |||
| private readonly ISchedulerFactory schedulerFactory; | |||
| public JobsService(ISchedulerFactory | |||
| schedulerFactory, | |||
| JobMetadata jobMetadata, | |||
| IJobFactory jobFactory) | |||
| { | |||
| this.schedulerFactory = schedulerFactory; | |||
| this.jobMetadata = jobMetadata; | |||
| this.jobFactory = jobFactory; | |||
| } | |||
| public IScheduler Scheduler { get; set; } | |||
| public async Task StartAsync(CancellationToken cancellationToken) | |||
| { | |||
| Scheduler = await schedulerFactory.GetScheduler(); | |||
| Scheduler.JobFactory = jobFactory; | |||
| var job = CreateJob(jobMetadata); | |||
| var trigger = CreateTrigger(jobMetadata); | |||
| await Scheduler.ScheduleJob(job, trigger, cancellationToken); | |||
| await Scheduler.Start(cancellationToken); | |||
| } | |||
| public async Task StopAsync(CancellationToken cancellationToken) | |||
| { | |||
| await Scheduler?.Shutdown(cancellationToken); | |||
| } | |||
| private ITrigger CreateTrigger(JobMetadata jobMetadata) | |||
| { | |||
| return TriggerBuilder.Create() | |||
| JobMetadata jobMetadata, | |||
| IJobFactory jobFactory) | |||
| { | |||
| this.schedulerFactory = schedulerFactory; | |||
| this.jobMetadata = jobMetadata; | |||
| this.jobFactory = jobFactory; | |||
| } | |||
| public IScheduler Scheduler { get; set; } | |||
| public async Task StartAsync(CancellationToken cancellationToken) | |||
| { | |||
| Scheduler = await schedulerFactory.GetScheduler(); | |||
| Scheduler.JobFactory = jobFactory; | |||
| var job = CreateJob(jobMetadata); | |||
| var trigger = CreateTrigger(jobMetadata); | |||
| await Scheduler.ScheduleJob(job, trigger, cancellationToken); | |||
| await Scheduler.Start(cancellationToken); | |||
| } | |||
| public async Task StopAsync(CancellationToken cancellationToken) | |||
| { | |||
| await Scheduler?.Shutdown(cancellationToken); | |||
| } | |||
| private ITrigger CreateTrigger(JobMetadata jobMetadata) | |||
| { | |||
| return TriggerBuilder.Create() | |||
| .WithIdentity(jobMetadata.JobId.ToString()) | |||
| .WithCronSchedule(jobMetadata.CronExpression) | |||
| .WithDescription($"{jobMetadata.JobName}") | |||
| .Build(); | |||
| } | |||
| private IJobDetail CreateJob(JobMetadata jobMetadata) | |||
| { | |||
| return JobBuilder | |||
| } | |||
| private IJobDetail CreateJob(JobMetadata jobMetadata) | |||
| { | |||
| return JobBuilder | |||
| .Create(jobMetadata.JobType) | |||
| .WithIdentity(jobMetadata.JobId.ToString()) | |||
| .WithDescription($"{jobMetadata.JobName}") | |||
| .Build(); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -1,28 +1,28 @@ | |||
| using SecureSharing.Business.Interfaces; | |||
| using Quartz; | |||
| using System; | |||
| using System; | |||
| using System.Threading.Tasks; | |||
| using Quartz; | |||
| using SecureSharing.Business.Interfaces; | |||
| namespace SecureSharing.Quartz | |||
| namespace SecureSharing.Quartz; | |||
| public sealed class MessageDeletionJob : IJob | |||
| { | |||
| public class MessageDeletionJob:IJob | |||
| private readonly IMessageService _messageService; | |||
| public MessageDeletionJob(IMessageService messageService) | |||
| { | |||
| _messageService = messageService; | |||
| } | |||
| public async Task Execute(IJobExecutionContext context) | |||
| { | |||
| private readonly IMessageService _messageService; | |||
| public MessageDeletionJob(IMessageService messageService) | |||
| try | |||
| { | |||
| _messageService = messageService; | |||
| await _messageService.DeleteExpiredMessages(); | |||
| } | |||
| public async Task Execute(IJobExecutionContext context) | |||
| catch (Exception ex) | |||
| { | |||
| try | |||
| { | |||
| await _messageService.DeleteExpiredMessages(); | |||
| } | |||
| catch (Exception ex) | |||
| { | |||
| /*Log*/ | |||
| } | |||
| return; | |||
| /*Log*/ | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -1,37 +1,37 @@ | |||
| <Project Sdk="Microsoft.NET.Sdk.Web"> | |||
| <PropertyGroup> | |||
| <TargetFramework>net6.0</TargetFramework> | |||
| <CopyRefAssembliesToPublishDirectory>false</CopyRefAssembliesToPublishDirectory> | |||
| <RootNamespace>SecureSharing</RootNamespace> | |||
| </PropertyGroup> | |||
| <PropertyGroup> | |||
| <TargetFramework>net6.0</TargetFramework> | |||
| <CopyRefAssembliesToPublishDirectory>false</CopyRefAssembliesToPublishDirectory> | |||
| <RootNamespace>SecureSharing</RootNamespace> | |||
| </PropertyGroup> | |||
| <ItemGroup> | |||
| <PackageReference Include="AutoMapper" Version="11.0.1" /> | |||
| <PackageReference Include="Microsoft.AspNet.Identity.Core" Version="2.2.3" /> | |||
| <PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="6.0.9" /> | |||
| <PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="6.0.9" /> | |||
| <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.9" /> | |||
| <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="6.0.9" /> | |||
| <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.9" /> | |||
| <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.9"> | |||
| <PrivateAssets>all</PrivateAssets> | |||
| <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | |||
| </PackageReference> | |||
| <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="6.0.9" /> | |||
| <PackageReference Include="Newtonsoft.Json" Version="13.0.1" /> | |||
| <PackageReference Include="Quartz" Version="3.5.0" /> | |||
| <PackageReference Include="Serilog" Version="2.12.0" /> | |||
| <PackageReference Include="Serilog.AspNetCore" Version="6.0.1" /> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <PackageReference Include="AutoMapper" Version="11.0.1"/> | |||
| <PackageReference Include="Microsoft.AspNet.Identity.Core" Version="2.2.3"/> | |||
| <PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="6.0.9"/> | |||
| <PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="6.0.9"/> | |||
| <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.9"/> | |||
| <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="6.0.9"/> | |||
| <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.9"/> | |||
| <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.9"> | |||
| <PrivateAssets>all</PrivateAssets> | |||
| <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | |||
| </PackageReference> | |||
| <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="6.0.9"/> | |||
| <PackageReference Include="Newtonsoft.Json" Version="13.0.1"/> | |||
| <PackageReference Include="Quartz" Version="3.5.0"/> | |||
| <PackageReference Include="Serilog" Version="2.12.0"/> | |||
| <PackageReference Include="Serilog.AspNetCore" Version="6.0.1"/> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <ProjectReference Include="..\SecureSharing.Business\SecureSharing.Business.csproj" /> | |||
| <ProjectReference Include="..\SecureSharing.Data\SecureSharing.Data.csproj" /> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <ProjectReference Include="..\SecureSharing.Business\SecureSharing.Business.csproj"/> | |||
| <ProjectReference Include="..\SecureSharing.Data\SecureSharing.Data.csproj"/> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <Folder Include="AppData\Errors\" /> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <Folder Include="AppData\Errors\"/> | |||
| </ItemGroup> | |||
| </Project> | |||
| @@ -1,10 +1,12 @@ | |||
| using Microsoft.AspNetCore.Builder; | |||
| using Microsoft.AspNetCore.Hosting; | |||
| using Microsoft.AspNetCore.HttpsPolicy; | |||
| using Microsoft.AspNetCore.Identity; | |||
| using Microsoft.Extensions.Configuration; | |||
| using Microsoft.Extensions.DependencyInjection; | |||
| using Microsoft.Extensions.Hosting; | |||
| using Quartz; | |||
| using Quartz.Impl; | |||
| using Quartz.Spi; | |||
| using SecureSharing.Business.Infrastructure; | |||
| using SecureSharing.Business.Infrastructure.Extensions; | |||
| using SecureSharing.Business.Infrastructure.Settings; | |||
| @@ -14,41 +16,34 @@ using SecureSharing.Data.DbContexts; | |||
| using SecureSharing.Infrastructure; | |||
| using SecureSharing.Infrastructure.Middleware; | |||
| using SecureSharing.Quartz; | |||
| using Quartz; | |||
| using Quartz.Impl; | |||
| using Quartz.Spi; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| using System.Threading.Tasks; | |||
| namespace SecureSharing | |||
| namespace SecureSharing; | |||
| public sealed class Startup | |||
| { | |||
| public class Startup | |||
| public Startup(IConfiguration configuration) | |||
| { | |||
| public Startup(IConfiguration configuration) | |||
| { | |||
| Configuration = configuration; | |||
| } | |||
| Configuration = configuration; | |||
| } | |||
| public IConfiguration Configuration { get; } | |||
| public IConfiguration Configuration { get; } | |||
| // This method gets called by the runtime. Use this method to add services to the container. | |||
| public void ConfigureServices(IServiceCollection services) | |||
| { | |||
| StartupConfiguration.ConfigureStartupConfig<EmailSettings>(services, Configuration); | |||
| services.AddControllersWithViews(); | |||
| services.AddRazorPages(); | |||
| StartupExtensions.ConfigureServices(services); | |||
| services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = false) | |||
| .AddDefaultUI() | |||
| .AddRoles<IdentityRole>() | |||
| .AddEntityFrameworkStores<AppDbContext>(); | |||
| services.AddScoped<IMessageService, MessageService>(); | |||
| services.AddScoped<IModelFactory, ModelFactory>(); | |||
| services.AddAuthentication() | |||
| // This method gets called by the runtime. Use this method to add services to the container. | |||
| public void ConfigureServices(IServiceCollection services) | |||
| { | |||
| StartupConfiguration.ConfigureStartupConfig<EmailSettings>(services, Configuration); | |||
| services.AddControllersWithViews(); | |||
| services.AddRazorPages(); | |||
| StartupExtensions.ConfigureServices(services); | |||
| services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = false) | |||
| .AddDefaultUI() | |||
| .AddRoles<IdentityRole>() | |||
| .AddEntityFrameworkStores<AppDbContext>(); | |||
| services.AddScoped<IMessageService, MessageService>(); | |||
| services.AddScoped<IModelFactory, ModelFactory>(); | |||
| services.AddAuthentication() | |||
| .AddGoogle(options => | |||
| { | |||
| options.ClientId = Configuration.GetSection("EmailSettings").GetSection("ClientId").Value; | |||
| @@ -56,51 +51,49 @@ namespace SecureSharing | |||
| }); | |||
| // Add Quartz services | |||
| services.AddSingleton<IJobFactory, JobFactory>(); | |||
| services.AddSingleton<ISchedulerFactory, StdSchedulerFactory>(); | |||
| // Add our jobs | |||
| services.AddScoped<MessageDeletionJob>(); | |||
| services.AddSingleton(new JobMetadata( | |||
| jobType: typeof(MessageDeletionJob), | |||
| cronExpression: "0 0 12 * * ?")); | |||
| // Add Quartz services | |||
| services.AddSingleton<IJobFactory, JobFactory>(); | |||
| services.AddSingleton<ISchedulerFactory, StdSchedulerFactory>(); | |||
| // Add our jobs | |||
| services.AddScoped<MessageDeletionJob>(); | |||
| services.AddSingleton(new JobMetadata( | |||
| typeof(MessageDeletionJob), | |||
| "0 0 12 * * ?")); | |||
| services.AddHostedService<JobsService>(); | |||
| services.AddHostedService<JobsService>(); | |||
| } | |||
| // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. | |||
| public void Configure(IApplicationBuilder app, IWebHostEnvironment env) | |||
| { | |||
| if (env.IsDevelopment()) | |||
| { | |||
| app.UseDeveloperExceptionPage(); | |||
| } | |||
| // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. | |||
| public void Configure(IApplicationBuilder app, IWebHostEnvironment env) | |||
| else | |||
| { | |||
| if (env.IsDevelopment()) | |||
| { | |||
| app.UseDeveloperExceptionPage(); | |||
| } | |||
| else | |||
| { | |||
| app.UseExceptionHandler("/Home/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(); | |||
| } | |||
| app.UseHttpsRedirection(); | |||
| app.UseStaticFiles(); | |||
| app.UseExceptionHandler("/Home/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(); | |||
| } | |||
| app.UseRouting(); | |||
| app.UseAuthentication(); | |||
| app.UseAuthorization(); | |||
| app.UseHttpsRedirection(); | |||
| app.UseStaticFiles(); | |||
| app.UseMiddleware(typeof(ExceptionHandlingMiddleware)); | |||
| app.UseRouting(); | |||
| app.UseAuthentication(); | |||
| app.UseAuthorization(); | |||
| app.UseEndpoints(endpoints => | |||
| { | |||
| endpoints.MapControllerRoute( | |||
| name: "default", | |||
| pattern: "{controller=Home}/{action=Index}/{id?}"); | |||
| endpoints.MapRazorPages(); | |||
| }); | |||
| } | |||
| app.UseMiddleware(typeof(ExceptionHandlingMiddleware)); | |||
| app.UseEndpoints(endpoints => | |||
| { | |||
| endpoints.MapControllerRoute( | |||
| "default", | |||
| "{controller=Home}/{action=Index}/{id?}"); | |||
| endpoints.MapRazorPages(); | |||
| }); | |||
| } | |||
| } | |||
| } | |||
| @@ -6,26 +6,25 @@ | |||
| <div class="text-center"> | |||
| <form method="post" asp-controller="Home" asp-action="CreateMessage"> | |||
| <input asp-for="Text" /> | |||
| <input asp-for="Text"/> | |||
| <br> | |||
| <input type="radio" asp-for="ChosenPeriod" value="@PeriodOfValidity.ONE_TIME" /> ONE TIME | |||
| <input type="radio" asp-for="ChosenPeriod" value="@PeriodOfValidity.ONE_TIME"/> ONE TIME | |||
| <br> | |||
| <input type="radio" asp-for="ChosenPeriod" value="@PeriodOfValidity.ONE_HOUR" /> ONE HOUR | |||
| <input type="radio" asp-for="ChosenPeriod" value="@PeriodOfValidity.ONE_HOUR"/> ONE HOUR | |||
| <br> | |||
| <input type="radio" asp-for="ChosenPeriod" value="@PeriodOfValidity.ONE_DAY" /> ONE DAY | |||
| <input type="radio" asp-for="ChosenPeriod" value="@PeriodOfValidity.ONE_DAY"/> ONE DAY | |||
| <br> | |||
| <input type="radio" asp-for="ChosenPeriod" value="@PeriodOfValidity.ONE_WEEK" /> SEVEN DAYS | |||
| <input type="radio" asp-for="ChosenPeriod" value="@PeriodOfValidity.ONE_WEEK"/> SEVEN DAYS | |||
| <br> | |||
| <button class = " btn btn-light" type="submit">Send</button> | |||
| <button class=" btn btn-light" type="submit">Send</button> | |||
| </form> | |||
| <br> | |||
| <br> | |||
| </div> | |||
| </div> | |||
| @@ -1,27 +1,27 @@ | |||
| | |||
| @{ | |||
| @{ | |||
| Layout = "~/Views/Shared/_Layout.cshtml"; | |||
| } | |||
| @model LinkModel | |||
| <div class="text-center"> | |||
| @if(!Model.IsValid) | |||
| @if (!Model.IsValid) | |||
| { | |||
| <p>This link has expired</p> | |||
| } | |||
| else | |||
| { | |||
| @if(Model.Share == true) | |||
| @if (Model.Share == true) | |||
| { | |||
| @Url.Action("Link", "Home", new { id = Model.message.Id }, "https") | |||
| } | |||
| else | |||
| { | |||
| @Url.Action(action: "Link", controller: "Home", values: new { id = @Model.message.Id }, protocol: "https") | |||
| }else{ | |||
| <div> | |||
| @if(Model.TimeLeft != null) | |||
| @if (Model.TimeLeft != null) | |||
| { | |||
| var time = Model.TimeLeft.Value; | |||
| if(time.Days > 0) | |||
| if (time.Days > 0) | |||
| { | |||
| <p>This message will expire in: @time.ToString("%d") days @time.ToString("%h") hours @time.ToString("%m") minutes</p> | |||
| } | |||
| @@ -35,15 +35,13 @@ | |||
| <p>This message will expire when you leave this page</p> | |||
| } | |||
| </div> | |||
| } | |||
| <div> | |||
| Message: @Model.message.Text | |||
| </div> | |||
| <div> | |||
| Message: @Model.message.Text | |||
| </div> | |||
| } | |||
| <a class="btn btn-light" asp-controller="Home" asp-action="Index">Back</a> | |||
| </div> | |||
| </div> | |||
| @@ -3,4 +3,4 @@ | |||
| } | |||
| <h1>@ViewData["Title"]</h1> | |||
| <p>Use this page to detail your site's privacy policy.</p> | |||
| <p>Use this page to detail your site's privacy policy.</p> | |||
| @@ -22,4 +22,4 @@ | |||
| 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> | |||
| </p> | |||
| @@ -5,8 +5,8 @@ | |||
| <!DOCTYPE html> | |||
| <html lang="en"> | |||
| <head> | |||
| <meta charset="utf-8" /> | |||
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |||
| <meta charset="utf-8"/> | |||
| <meta name="viewport" content="width=device-width, initial-scale=1.0"/> | |||
| <title>@ViewData["Title"] - SecureSharing</title> | |||
| <!-- Google Font: Source Sans Pro --> | |||
| <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700&display=fallback"> | |||
| @@ -30,82 +30,81 @@ | |||
| <link rel="stylesheet" href="~/plugins/summernote/summernote-bs4.min.css"> | |||
| <link href="~/lib/jquery-confirm/jquery-confirm.min.css" rel="stylesheet" /> | |||
| <link href="~/lib/jquery-confirm/jquery-confirm.min.css" rel="stylesheet"/> | |||
| <link rel="stylesheet" href="~/css/site.css"> | |||
| </head> | |||
| <body class="hold-transition layout-fixed"> | |||
| <noscript><p>Your browser does not support JavaScript. You need it enabled to do testing.</p></noscript> | |||
| <noscript> | |||
| <p>Your browser does not support JavaScript. You need it enabled to do testing.</p> | |||
| </noscript> | |||
| <div class="wrapper"> | |||
| <div class="wrapper"> | |||
| <div class="content-wrapper default-layout"> | |||
| <section class="content"> | |||
| <main role="main" class="pb-3"> | |||
| <div class="content-fluid"> | |||
| <div> </div> | |||
| <div class="card"> | |||
| <div class="card-body"> | |||
| @RenderBody() | |||
| </div> | |||
| <div class="content-wrapper default-layout"> | |||
| <section class="content"> | |||
| <main role="main" class="pb-3"> | |||
| <div class="content-fluid"> | |||
| <div> </div> | |||
| <div class="card"> | |||
| <div class="card-body"> | |||
| @RenderBody() | |||
| </div> | |||
| </div> | |||
| </main> | |||
| </section> | |||
| </div> | |||
| <footer class="main-footer ml-0"> | |||
| <strong>Copyright © 2021 <a href="https://dilig.net/">Diligent Software</a>.</strong> | |||
| All rights reserved. | |||
| <div class="float-right d-none d-sm-inline-block"> | |||
| <b>Version</b> 1.0.0-alpha | |||
| </div> | |||
| </footer> | |||
| </div> | |||
| </main> | |||
| </section> | |||
| </div> | |||
| <!-- jQuery --> | |||
| <script src="~/plugins/jquery/jquery.min.js"></script> | |||
| <!-- jQuery UI 1.11.4 --> | |||
| <script src="~/plugins/jquery-ui/jquery-ui.min.js"></script> | |||
| <!-- Resolve conflict in jQuery UI tooltip with Bootstrap tooltip --> | |||
| <script> | |||
| <footer class="main-footer ml-0"> | |||
| <strong>Copyright © 2021 <a href="https://dilig.net/">Diligent Software</a>.</strong> | |||
| All rights reserved. | |||
| <div class="float-right d-none d-sm-inline-block"> | |||
| <b>Version</b> 1.0.0-alpha | |||
| </div> | |||
| </footer> | |||
| </div> | |||
| <!-- jQuery --> | |||
| <script src="~/plugins/jquery/jquery.min.js"></script> | |||
| <!-- jQuery UI 1.11.4 --> | |||
| <script src="~/plugins/jquery-ui/jquery-ui.min.js"></script> | |||
| <!-- Resolve conflict in jQuery UI tooltip with Bootstrap tooltip --> | |||
| <script> | |||
| $.widget.bridge('uibutton', $.ui.button) | |||
| </script> | |||
| <!-- Bootstrap 4 --> | |||
| <script src="~/plugins/bootstrap/js/bootstrap.bundle.min.js"></script> | |||
| <!-- ChartJS --> | |||
| <script src="~/plugins/chart.js/Chart.min.js"></script> | |||
| <!-- Sparkline --> | |||
| <script src="~/plugins/sparklines/sparkline.js"></script> | |||
| <!-- JQVMap --> | |||
| <script src="~/plugins/jqvmap/jquery.vmap.min.js"></script> | |||
| <script src="~/plugins/jqvmap/maps/jquery.vmap.usa.js"></script> | |||
| <!-- jQuery Knob Chart --> | |||
| <script src="~/plugins/jquery-knob/jquery.knob.min.js"></script> | |||
| <!-- daterangepicker --> | |||
| <script src="~/plugins/moment/moment.min.js"></script> | |||
| <script src="~/plugins/daterangepicker/daterangepicker.js"></script> | |||
| <!-- Tempusdominus Bootstrap 4 --> | |||
| <script src="~/plugins/tempusdominus-bootstrap-4/js/tempusdominus-bootstrap-4.min.js"></script> | |||
| <!-- Summernote --> | |||
| <script src="~/plugins/summernote/summernote-bs4.min.js"></script> | |||
| <!-- overlayScrollbars --> | |||
| <script src="~/plugins/overlayScrollbars/js/jquery.overlayScrollbars.min.js"></script> | |||
| <!-- AdminLTE App --> | |||
| <script src="~/dist/js/adminlte.js"></script> | |||
| <!-- Bootstrap 4 --> | |||
| <script src="~/plugins/bootstrap/js/bootstrap.bundle.min.js"></script> | |||
| <!-- ChartJS --> | |||
| <script src="~/plugins/chart.js/Chart.min.js"></script> | |||
| <!-- Sparkline --> | |||
| <script src="~/plugins/sparklines/sparkline.js"></script> | |||
| <!-- JQVMap --> | |||
| <script src="~/plugins/jqvmap/jquery.vmap.min.js"></script> | |||
| <script src="~/plugins/jqvmap/maps/jquery.vmap.usa.js"></script> | |||
| <!-- jQuery Knob Chart --> | |||
| <script src="~/plugins/jquery-knob/jquery.knob.min.js"></script> | |||
| <!-- daterangepicker --> | |||
| <script src="~/plugins/moment/moment.min.js"></script> | |||
| <script src="~/plugins/daterangepicker/daterangepicker.js"></script> | |||
| <!-- Tempusdominus Bootstrap 4 --> | |||
| <script src="~/plugins/tempusdominus-bootstrap-4/js/tempusdominus-bootstrap-4.min.js"></script> | |||
| <!-- Summernote --> | |||
| <script src="~/plugins/summernote/summernote-bs4.min.js"></script> | |||
| <!-- overlayScrollbars --> | |||
| <script src="~/plugins/overlayScrollbars/js/jquery.overlayScrollbars.min.js"></script> | |||
| <!-- AdminLTE App --> | |||
| <script src="~/dist/js/adminlte.js"></script> | |||
| <!-- JQery Confirm --> | |||
| <!-- JQery Confirm --> | |||
| <script src="~/lib/alertifyjs/alertify.min.js"></script> | |||
| <script src="~/lib/blockUI/jquery.blockUI.js"></script> | |||
| <script src="~/lib/alertifyjs/alertify.min.js"></script> | |||
| <script src="~/lib/blockUI/jquery.blockUI.js"></script> | |||
| <script src="~/js/site.js" asp-append-version="true"></script> | |||
| <script src="~/js/site.js" asp-append-version="true"></script> | |||
| @await RenderSectionAsync("Scripts", required: false) | |||
| @await RenderSectionAsync("Scripts", false) | |||
| </body> | |||
| </html> | |||
| </html> | |||
| @@ -1,2 +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> | |||
| <script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script> | |||
| @@ -1,3 +1,3 @@ | |||
| @using SecureSharing | |||
| @using SecureSharing.Models | |||
| @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers | |||
| @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers | |||
| @@ -1,3 +1,3 @@ | |||
| @{ | |||
| Layout = "_Layout"; | |||
| } | |||
| } | |||
| @@ -1,9 +1,7 @@ | |||
| { | |||
| "AllowedHosts": "*", | |||
| "ConnectionStrings": { | |||
| "DefaultConnection": "data source=(localdb)\\MSSQLLocalDB; initial catalog=Test;Integrated Security=True" | |||
| }, | |||
| "Logging": { | |||
| "LogLevel": { | |||
| @@ -1,17 +1,17 @@ | |||
| 'use strict' | |||
| module.exports = { | |||
| map: { | |||
| inline: false, | |||
| annotation: true, | |||
| sourcesContent: true | |||
| }, | |||
| plugins: [ | |||
| require('postcss-scrollbar')({ | |||
| edgeAutohide: true | |||
| }), | |||
| require('autoprefixer')({ | |||
| cascade: false | |||
| }) | |||
| ] | |||
| map: { | |||
| inline: false, | |||
| annotation: true, | |||
| sourcesContent: true | |||
| }, | |||
| plugins: [ | |||
| require('postcss-scrollbar')({ | |||
| edgeAutohide: true | |||
| }), | |||
| require('autoprefixer')({ | |||
| cascade: false | |||
| }) | |||
| ] | |||
| } | |||
| @@ -1,6 +1,6 @@ | |||
| 'use strict' | |||
| const { babel } = require('@rollup/plugin-babel') | |||
| const {babel} = require('@rollup/plugin-babel') | |||
| const pkg = require('../../package') | |||
| const year = new Date().getFullYear() | |||
| @@ -11,22 +11,22 @@ const banner = `/*! | |||
| */` | |||
| module.exports = { | |||
| input: 'build/js/AdminLTE.js', | |||
| output: { | |||
| banner, | |||
| file: 'dist/js/adminlte.js', | |||
| format: 'umd', | |||
| globals: { | |||
| jquery: 'jQuery' | |||
| input: 'build/js/AdminLTE.js', | |||
| output: { | |||
| banner, | |||
| file: 'dist/js/adminlte.js', | |||
| format: 'umd', | |||
| globals: { | |||
| jquery: 'jQuery' | |||
| }, | |||
| name: 'adminlte' | |||
| }, | |||
| name: 'adminlte' | |||
| }, | |||
| external: ['jquery'], | |||
| plugins: [ | |||
| babel({ | |||
| exclude: 'node_modules/**', | |||
| // Include the helpers in the bundle, at most one copy of each | |||
| babelHelpers: 'bundled' | |||
| }) | |||
| ] | |||
| external: ['jquery'], | |||
| plugins: [ | |||
| babel({ | |||
| exclude: 'node_modules/**', | |||
| // Include the helpers in the bundle, at most one copy of each | |||
| babelHelpers: 'bundled' | |||
| }) | |||
| ] | |||
| } | |||
| @@ -15,19 +15,19 @@ import TodoList from './TodoList' | |||
| import Treeview from './Treeview' | |||
| export { | |||
| CardRefresh, | |||
| CardWidget, | |||
| ControlSidebar, | |||
| DirectChat, | |||
| Dropdown, | |||
| ExpandableTable, | |||
| Fullscreen, | |||
| IFrame, | |||
| Layout, | |||
| PushMenu, | |||
| SidebarSearch, | |||
| NavbarSearch, | |||
| Toasts, | |||
| TodoList, | |||
| Treeview | |||
| CardRefresh, | |||
| CardWidget, | |||
| ControlSidebar, | |||
| DirectChat, | |||
| Dropdown, | |||
| ExpandableTable, | |||
| Fullscreen, | |||
| IFrame, | |||
| Layout, | |||
| PushMenu, | |||
| SidebarSearch, | |||
| NavbarSearch, | |||
| Toasts, | |||
| TodoList, | |||
| Treeview | |||
| } | |||
| @@ -27,96 +27,97 @@ const SELECTOR_CARD = `.${CLASS_NAME_CARD}` | |||
| const SELECTOR_DATA_REFRESH = '[data-card-widget="card-refresh"]' | |||
| const Default = { | |||
| source: '', | |||
| sourceSelector: '', | |||
| params: {}, | |||
| trigger: SELECTOR_DATA_REFRESH, | |||
| content: '.card-body', | |||
| loadInContent: true, | |||
| loadOnInit: true, | |||
| responseType: '', | |||
| overlayTemplate: '<div class="overlay"><i class="fas fa-2x fa-sync-alt fa-spin"></i></div>', | |||
| onLoadStart() {}, | |||
| onLoadDone(response) { | |||
| return response | |||
| } | |||
| source: '', | |||
| sourceSelector: '', | |||
| params: {}, | |||
| trigger: SELECTOR_DATA_REFRESH, | |||
| content: '.card-body', | |||
| loadInContent: true, | |||
| loadOnInit: true, | |||
| responseType: '', | |||
| overlayTemplate: '<div class="overlay"><i class="fas fa-2x fa-sync-alt fa-spin"></i></div>', | |||
| onLoadStart() { | |||
| }, | |||
| onLoadDone(response) { | |||
| return response | |||
| } | |||
| } | |||
| class CardRefresh { | |||
| constructor(element, settings) { | |||
| this._element = element | |||
| this._parent = element.parents(SELECTOR_CARD).first() | |||
| this._settings = $.extend({}, Default, settings) | |||
| this._overlay = $(this._settings.overlayTemplate) | |||
| if (element.hasClass(CLASS_NAME_CARD)) { | |||
| this._parent = element | |||
| } | |||
| constructor(element, settings) { | |||
| this._element = element | |||
| this._parent = element.parents(SELECTOR_CARD).first() | |||
| this._settings = $.extend({}, Default, settings) | |||
| this._overlay = $(this._settings.overlayTemplate) | |||
| if (element.hasClass(CLASS_NAME_CARD)) { | |||
| this._parent = element | |||
| } | |||
| if (this._settings.source === '') { | |||
| throw new Error('Source url was not defined. Please specify a url in your CardRefresh source option.') | |||
| if (this._settings.source === '') { | |||
| throw new Error('Source url was not defined. Please specify a url in your CardRefresh source option.') | |||
| } | |||
| } | |||
| } | |||
| load() { | |||
| this._addOverlay() | |||
| this._settings.onLoadStart.call($(this)) | |||
| static _jQueryInterface(config) { | |||
| let data = $(this).data(DATA_KEY) | |||
| const _options = $.extend({}, Default, $(this).data()) | |||
| $.get(this._settings.source, this._settings.params, response => { | |||
| if (this._settings.loadInContent) { | |||
| if (this._settings.sourceSelector !== '') { | |||
| response = $(response).find(this._settings.sourceSelector).html() | |||
| if (!data) { | |||
| data = new CardRefresh($(this), _options) | |||
| $(this).data(DATA_KEY, typeof config === 'string' ? data : config) | |||
| } | |||
| this._parent.find(this._settings.content).html(response) | |||
| } | |||
| this._settings.onLoadDone.call($(this), response) | |||
| this._removeOverlay() | |||
| }, this._settings.responseType !== '' && this._settings.responseType) | |||
| if (typeof config === 'string' && /load/.test(config)) { | |||
| data[config]() | |||
| } else { | |||
| data._init($(this)) | |||
| } | |||
| } | |||
| $(this._element).trigger($.Event(EVENT_LOADED)) | |||
| } | |||
| load() { | |||
| this._addOverlay() | |||
| this._settings.onLoadStart.call($(this)) | |||
| _addOverlay() { | |||
| this._parent.append(this._overlay) | |||
| $(this._element).trigger($.Event(EVENT_OVERLAY_ADDED)) | |||
| } | |||
| $.get(this._settings.source, this._settings.params, response => { | |||
| if (this._settings.loadInContent) { | |||
| if (this._settings.sourceSelector !== '') { | |||
| response = $(response).find(this._settings.sourceSelector).html() | |||
| } | |||
| _removeOverlay() { | |||
| this._parent.find(this._overlay).remove() | |||
| $(this._element).trigger($.Event(EVENT_OVERLAY_REMOVED)) | |||
| } | |||
| this._parent.find(this._settings.content).html(response) | |||
| } | |||
| // Private | |||
| this._settings.onLoadDone.call($(this), response) | |||
| this._removeOverlay() | |||
| }, this._settings.responseType !== '' && this._settings.responseType) | |||
| _init() { | |||
| $(this).find(this._settings.trigger).on('click', () => { | |||
| this.load() | |||
| }) | |||
| if (this._settings.loadOnInit) { | |||
| this.load() | |||
| $(this._element).trigger($.Event(EVENT_LOADED)) | |||
| } | |||
| } | |||
| // Static | |||
| _addOverlay() { | |||
| this._parent.append(this._overlay) | |||
| $(this._element).trigger($.Event(EVENT_OVERLAY_ADDED)) | |||
| } | |||
| static _jQueryInterface(config) { | |||
| let data = $(this).data(DATA_KEY) | |||
| const _options = $.extend({}, Default, $(this).data()) | |||
| // Private | |||
| if (!data) { | |||
| data = new CardRefresh($(this), _options) | |||
| $(this).data(DATA_KEY, typeof config === 'string' ? data : config) | |||
| _removeOverlay() { | |||
| this._parent.find(this._overlay).remove() | |||
| $(this._element).trigger($.Event(EVENT_OVERLAY_REMOVED)) | |||
| } | |||
| if (typeof config === 'string' && /load/.test(config)) { | |||
| data[config]() | |||
| } else { | |||
| data._init($(this)) | |||
| // Static | |||
| _init() { | |||
| $(this).find(this._settings.trigger).on('click', () => { | |||
| this.load() | |||
| }) | |||
| if (this._settings.loadOnInit) { | |||
| this.load() | |||
| } | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| @@ -125,17 +126,17 @@ class CardRefresh { | |||
| */ | |||
| $(document).on('click', SELECTOR_DATA_REFRESH, function (event) { | |||
| if (event) { | |||
| event.preventDefault() | |||
| } | |||
| if (event) { | |||
| event.preventDefault() | |||
| } | |||
| CardRefresh._jQueryInterface.call($(this), 'load') | |||
| CardRefresh._jQueryInterface.call($(this), 'load') | |||
| }) | |||
| $(() => { | |||
| $(SELECTOR_DATA_REFRESH).each(function () { | |||
| CardRefresh._jQueryInterface.call($(this)) | |||
| }) | |||
| $(SELECTOR_DATA_REFRESH).each(function () { | |||
| CardRefresh._jQueryInterface.call($(this)) | |||
| }) | |||
| }) | |||
| /** | |||
| @@ -146,8 +147,8 @@ $(() => { | |||
| $.fn[NAME] = CardRefresh._jQueryInterface | |||
| $.fn[NAME].Constructor = CardRefresh | |||
| $.fn[NAME].noConflict = function () { | |||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||
| return CardRefresh._jQueryInterface | |||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||
| return CardRefresh._jQueryInterface | |||
| } | |||
| export default CardRefresh | |||
| @@ -39,159 +39,159 @@ const SELECTOR_CARD_BODY = '.card-body' | |||
| const SELECTOR_CARD_FOOTER = '.card-footer' | |||
| const Default = { | |||
| animationSpeed: 'normal', | |||
| collapseTrigger: SELECTOR_DATA_COLLAPSE, | |||
| removeTrigger: SELECTOR_DATA_REMOVE, | |||
| maximizeTrigger: SELECTOR_DATA_MAXIMIZE, | |||
| collapseIcon: 'fa-minus', | |||
| expandIcon: 'fa-plus', | |||
| maximizeIcon: 'fa-expand', | |||
| minimizeIcon: 'fa-compress' | |||
| animationSpeed: 'normal', | |||
| collapseTrigger: SELECTOR_DATA_COLLAPSE, | |||
| removeTrigger: SELECTOR_DATA_REMOVE, | |||
| maximizeTrigger: SELECTOR_DATA_MAXIMIZE, | |||
| collapseIcon: 'fa-minus', | |||
| expandIcon: 'fa-plus', | |||
| maximizeIcon: 'fa-expand', | |||
| minimizeIcon: 'fa-compress' | |||
| } | |||
| class CardWidget { | |||
| constructor(element, settings) { | |||
| this._element = element | |||
| this._parent = element.parents(SELECTOR_CARD).first() | |||
| constructor(element, settings) { | |||
| this._element = element | |||
| this._parent = element.parents(SELECTOR_CARD).first() | |||
| if (element.hasClass(CLASS_NAME_CARD)) { | |||
| this._parent = element | |||
| if (element.hasClass(CLASS_NAME_CARD)) { | |||
| this._parent = element | |||
| } | |||
| this._settings = $.extend({}, Default, settings) | |||
| } | |||
| this._settings = $.extend({}, Default, settings) | |||
| } | |||
| static _jQueryInterface(config) { | |||
| let data = $(this).data(DATA_KEY) | |||
| const _options = $.extend({}, Default, $(this).data()) | |||
| collapse() { | |||
| this._parent.addClass(CLASS_NAME_COLLAPSING).children(`${SELECTOR_CARD_BODY}, ${SELECTOR_CARD_FOOTER}`) | |||
| .slideUp(this._settings.animationSpeed, () => { | |||
| this._parent.addClass(CLASS_NAME_COLLAPSED).removeClass(CLASS_NAME_COLLAPSING) | |||
| }) | |||
| if (!data) { | |||
| data = new CardWidget($(this), _options) | |||
| $(this).data(DATA_KEY, typeof config === 'string' ? data : config) | |||
| } | |||
| this._parent.find(`> ${SELECTOR_CARD_HEADER} ${this._settings.collapseTrigger} .${this._settings.collapseIcon}`) | |||
| .addClass(this._settings.expandIcon) | |||
| .removeClass(this._settings.collapseIcon) | |||
| if (typeof config === 'string' && /collapse|expand|remove|toggle|maximize|minimize|toggleMaximize/.test(config)) { | |||
| data[config]() | |||
| } else if (typeof config === 'object') { | |||
| data._init($(this)) | |||
| } | |||
| } | |||
| this._element.trigger($.Event(EVENT_COLLAPSED), this._parent) | |||
| } | |||
| collapse() { | |||
| this._parent.addClass(CLASS_NAME_COLLAPSING).children(`${SELECTOR_CARD_BODY}, ${SELECTOR_CARD_FOOTER}`) | |||
| .slideUp(this._settings.animationSpeed, () => { | |||
| this._parent.addClass(CLASS_NAME_COLLAPSED).removeClass(CLASS_NAME_COLLAPSING) | |||
| }) | |||
| expand() { | |||
| this._parent.addClass(CLASS_NAME_EXPANDING).children(`${SELECTOR_CARD_BODY}, ${SELECTOR_CARD_FOOTER}`) | |||
| .slideDown(this._settings.animationSpeed, () => { | |||
| this._parent.removeClass(CLASS_NAME_COLLAPSED).removeClass(CLASS_NAME_EXPANDING) | |||
| }) | |||
| this._parent.find(`> ${SELECTOR_CARD_HEADER} ${this._settings.collapseTrigger} .${this._settings.collapseIcon}`) | |||
| .addClass(this._settings.expandIcon) | |||
| .removeClass(this._settings.collapseIcon) | |||
| this._parent.find(`> ${SELECTOR_CARD_HEADER} ${this._settings.collapseTrigger} .${this._settings.expandIcon}`) | |||
| .addClass(this._settings.collapseIcon) | |||
| .removeClass(this._settings.expandIcon) | |||
| this._element.trigger($.Event(EVENT_COLLAPSED), this._parent) | |||
| } | |||
| this._element.trigger($.Event(EVENT_EXPANDED), this._parent) | |||
| } | |||
| expand() { | |||
| this._parent.addClass(CLASS_NAME_EXPANDING).children(`${SELECTOR_CARD_BODY}, ${SELECTOR_CARD_FOOTER}`) | |||
| .slideDown(this._settings.animationSpeed, () => { | |||
| this._parent.removeClass(CLASS_NAME_COLLAPSED).removeClass(CLASS_NAME_EXPANDING) | |||
| }) | |||
| remove() { | |||
| this._parent.slideUp() | |||
| this._element.trigger($.Event(EVENT_REMOVED), this._parent) | |||
| } | |||
| this._parent.find(`> ${SELECTOR_CARD_HEADER} ${this._settings.collapseTrigger} .${this._settings.expandIcon}`) | |||
| .addClass(this._settings.collapseIcon) | |||
| .removeClass(this._settings.expandIcon) | |||
| toggle() { | |||
| if (this._parent.hasClass(CLASS_NAME_COLLAPSED)) { | |||
| this.expand() | |||
| return | |||
| this._element.trigger($.Event(EVENT_EXPANDED), this._parent) | |||
| } | |||
| this.collapse() | |||
| } | |||
| maximize() { | |||
| this._parent.find(`${this._settings.maximizeTrigger} .${this._settings.maximizeIcon}`) | |||
| .addClass(this._settings.minimizeIcon) | |||
| .removeClass(this._settings.maximizeIcon) | |||
| this._parent.css({ | |||
| height: this._parent.height(), | |||
| width: this._parent.width(), | |||
| transition: 'all .15s' | |||
| }).delay(150).queue(function () { | |||
| const $element = $(this) | |||
| $element.addClass(CLASS_NAME_MAXIMIZED) | |||
| $('html').addClass(CLASS_NAME_MAXIMIZED) | |||
| if ($element.hasClass(CLASS_NAME_COLLAPSED)) { | |||
| $element.addClass(CLASS_NAME_WAS_COLLAPSED) | |||
| } | |||
| $element.dequeue() | |||
| }) | |||
| this._element.trigger($.Event(EVENT_MAXIMIZED), this._parent) | |||
| } | |||
| minimize() { | |||
| this._parent.find(`${this._settings.maximizeTrigger} .${this._settings.minimizeIcon}`) | |||
| .addClass(this._settings.maximizeIcon) | |||
| .removeClass(this._settings.minimizeIcon) | |||
| this._parent.css('cssText', `height: ${this._parent[0].style.height} !important; width: ${this._parent[0].style.width} !important; transition: all .15s;` | |||
| ).delay(10).queue(function () { | |||
| const $element = $(this) | |||
| $element.removeClass(CLASS_NAME_MAXIMIZED) | |||
| $('html').removeClass(CLASS_NAME_MAXIMIZED) | |||
| $element.css({ | |||
| height: 'inherit', | |||
| width: 'inherit' | |||
| }) | |||
| if ($element.hasClass(CLASS_NAME_WAS_COLLAPSED)) { | |||
| $element.removeClass(CLASS_NAME_WAS_COLLAPSED) | |||
| } | |||
| $element.dequeue() | |||
| }) | |||
| this._element.trigger($.Event(EVENT_MINIMIZED), this._parent) | |||
| } | |||
| toggleMaximize() { | |||
| if (this._parent.hasClass(CLASS_NAME_MAXIMIZED)) { | |||
| this.minimize() | |||
| return | |||
| remove() { | |||
| this._parent.slideUp() | |||
| this._element.trigger($.Event(EVENT_REMOVED), this._parent) | |||
| } | |||
| this.maximize() | |||
| } | |||
| toggle() { | |||
| if (this._parent.hasClass(CLASS_NAME_COLLAPSED)) { | |||
| this.expand() | |||
| return | |||
| } | |||
| // Private | |||
| this.collapse() | |||
| } | |||
| _init(card) { | |||
| this._parent = card | |||
| maximize() { | |||
| this._parent.find(`${this._settings.maximizeTrigger} .${this._settings.maximizeIcon}`) | |||
| .addClass(this._settings.minimizeIcon) | |||
| .removeClass(this._settings.maximizeIcon) | |||
| this._parent.css({ | |||
| height: this._parent.height(), | |||
| width: this._parent.width(), | |||
| transition: 'all .15s' | |||
| }).delay(150).queue(function () { | |||
| const $element = $(this) | |||
| $element.addClass(CLASS_NAME_MAXIMIZED) | |||
| $('html').addClass(CLASS_NAME_MAXIMIZED) | |||
| if ($element.hasClass(CLASS_NAME_COLLAPSED)) { | |||
| $element.addClass(CLASS_NAME_WAS_COLLAPSED) | |||
| } | |||
| $element.dequeue() | |||
| }) | |||
| this._element.trigger($.Event(EVENT_MAXIMIZED), this._parent) | |||
| } | |||
| $(this).find(this._settings.collapseTrigger).click(() => { | |||
| this.toggle() | |||
| }) | |||
| minimize() { | |||
| this._parent.find(`${this._settings.maximizeTrigger} .${this._settings.minimizeIcon}`) | |||
| .addClass(this._settings.maximizeIcon) | |||
| .removeClass(this._settings.minimizeIcon) | |||
| this._parent.css('cssText', `height: ${this._parent[0].style.height} !important; width: ${this._parent[0].style.width} !important; transition: all .15s;` | |||
| ).delay(10).queue(function () { | |||
| const $element = $(this) | |||
| $element.removeClass(CLASS_NAME_MAXIMIZED) | |||
| $('html').removeClass(CLASS_NAME_MAXIMIZED) | |||
| $element.css({ | |||
| height: 'inherit', | |||
| width: 'inherit' | |||
| }) | |||
| if ($element.hasClass(CLASS_NAME_WAS_COLLAPSED)) { | |||
| $element.removeClass(CLASS_NAME_WAS_COLLAPSED) | |||
| } | |||
| $element.dequeue() | |||
| }) | |||
| this._element.trigger($.Event(EVENT_MINIMIZED), this._parent) | |||
| } | |||
| $(this).find(this._settings.maximizeTrigger).click(() => { | |||
| this.toggleMaximize() | |||
| }) | |||
| // Private | |||
| $(this).find(this._settings.removeTrigger).click(() => { | |||
| this.remove() | |||
| }) | |||
| } | |||
| toggleMaximize() { | |||
| if (this._parent.hasClass(CLASS_NAME_MAXIMIZED)) { | |||
| this.minimize() | |||
| return | |||
| } | |||
| // Static | |||
| this.maximize() | |||
| } | |||
| static _jQueryInterface(config) { | |||
| let data = $(this).data(DATA_KEY) | |||
| const _options = $.extend({}, Default, $(this).data()) | |||
| // Static | |||
| if (!data) { | |||
| data = new CardWidget($(this), _options) | |||
| $(this).data(DATA_KEY, typeof config === 'string' ? data : config) | |||
| } | |||
| _init(card) { | |||
| this._parent = card | |||
| $(this).find(this._settings.collapseTrigger).click(() => { | |||
| this.toggle() | |||
| }) | |||
| $(this).find(this._settings.maximizeTrigger).click(() => { | |||
| this.toggleMaximize() | |||
| }) | |||
| if (typeof config === 'string' && /collapse|expand|remove|toggle|maximize|minimize|toggleMaximize/.test(config)) { | |||
| data[config]() | |||
| } else if (typeof config === 'object') { | |||
| data._init($(this)) | |||
| $(this).find(this._settings.removeTrigger).click(() => { | |||
| this.remove() | |||
| }) | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| @@ -200,27 +200,27 @@ class CardWidget { | |||
| */ | |||
| $(document).on('click', SELECTOR_DATA_COLLAPSE, function (event) { | |||
| if (event) { | |||
| event.preventDefault() | |||
| } | |||
| if (event) { | |||
| event.preventDefault() | |||
| } | |||
| CardWidget._jQueryInterface.call($(this), 'toggle') | |||
| CardWidget._jQueryInterface.call($(this), 'toggle') | |||
| }) | |||
| $(document).on('click', SELECTOR_DATA_REMOVE, function (event) { | |||
| if (event) { | |||
| event.preventDefault() | |||
| } | |||
| if (event) { | |||
| event.preventDefault() | |||
| } | |||
| CardWidget._jQueryInterface.call($(this), 'remove') | |||
| CardWidget._jQueryInterface.call($(this), 'remove') | |||
| }) | |||
| $(document).on('click', SELECTOR_DATA_MAXIMIZE, function (event) { | |||
| if (event) { | |||
| event.preventDefault() | |||
| } | |||
| if (event) { | |||
| event.preventDefault() | |||
| } | |||
| CardWidget._jQueryInterface.call($(this), 'toggleMaximize') | |||
| CardWidget._jQueryInterface.call($(this), 'toggleMaximize') | |||
| }) | |||
| /** | |||
| @@ -231,8 +231,8 @@ $(document).on('click', SELECTOR_DATA_MAXIMIZE, function (event) { | |||
| $.fn[NAME] = CardWidget._jQueryInterface | |||
| $.fn[NAME].Constructor = CardWidget | |||
| $.fn[NAME].noConflict = function () { | |||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||
| return CardWidget._jQueryInterface | |||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||
| return CardWidget._jQueryInterface | |||
| } | |||
| export default CardWidget | |||
| @@ -42,10 +42,10 @@ const CLASS_NAME_FOOTER_LG_FIXED = 'layout-lg-footer-fixed' | |||
| const CLASS_NAME_FOOTER_XL_FIXED = 'layout-xl-footer-fixed' | |||
| const Default = { | |||
| controlsidebarSlide: true, | |||
| scrollbarTheme: 'os-theme-light', | |||
| scrollbarAutoHide: 'l', | |||
| target: SELECTOR_CONTROL_SIDEBAR | |||
| controlsidebarSlide: true, | |||
| scrollbarTheme: 'os-theme-light', | |||
| scrollbarAutoHide: 'l', | |||
| target: SELECTOR_CONTROL_SIDEBAR | |||
| } | |||
| /** | |||
| @@ -54,242 +54,242 @@ const Default = { | |||
| */ | |||
| class ControlSidebar { | |||
| constructor(element, config) { | |||
| this._element = element | |||
| this._config = config | |||
| } | |||
| // Public | |||
| collapse() { | |||
| const $body = $('body') | |||
| const $html = $('html') | |||
| const { target } = this._config | |||
| // Show the control sidebar | |||
| if (this._config.controlsidebarSlide) { | |||
| $html.addClass(CLASS_NAME_CONTROL_SIDEBAR_ANIMATE) | |||
| $body.removeClass(CLASS_NAME_CONTROL_SIDEBAR_SLIDE).delay(300).queue(function () { | |||
| $(target).hide() | |||
| $html.removeClass(CLASS_NAME_CONTROL_SIDEBAR_ANIMATE) | |||
| $(this).dequeue() | |||
| }) | |||
| } else { | |||
| $body.removeClass(CLASS_NAME_CONTROL_SIDEBAR_OPEN) | |||
| constructor(element, config) { | |||
| this._element = element | |||
| this._config = config | |||
| } | |||
| $(this._element).trigger($.Event(EVENT_COLLAPSED)) | |||
| } | |||
| // Public | |||
| show() { | |||
| const $body = $('body') | |||
| const $html = $('html') | |||
| static _jQueryInterface(operation) { | |||
| return this.each(function () { | |||
| let data = $(this).data(DATA_KEY) | |||
| const _options = $.extend({}, Default, $(this).data()) | |||
| // Collapse the control sidebar | |||
| if (this._config.controlsidebarSlide) { | |||
| $html.addClass(CLASS_NAME_CONTROL_SIDEBAR_ANIMATE) | |||
| $(this._config.target).show().delay(10).queue(function () { | |||
| $body.addClass(CLASS_NAME_CONTROL_SIDEBAR_SLIDE).delay(300).queue(function () { | |||
| $html.removeClass(CLASS_NAME_CONTROL_SIDEBAR_ANIMATE) | |||
| $(this).dequeue() | |||
| if (!data) { | |||
| data = new ControlSidebar(this, _options) | |||
| $(this).data(DATA_KEY, data) | |||
| } | |||
| if (data[operation] === 'undefined') { | |||
| throw new Error(`${operation} is not a function`) | |||
| } | |||
| data[operation]() | |||
| }) | |||
| $(this).dequeue() | |||
| }) | |||
| } else { | |||
| $body.addClass(CLASS_NAME_CONTROL_SIDEBAR_OPEN) | |||
| } | |||
| this._fixHeight() | |||
| this._fixScrollHeight() | |||
| collapse() { | |||
| const $body = $('body') | |||
| const $html = $('html') | |||
| const {target} = this._config | |||
| // Show the control sidebar | |||
| if (this._config.controlsidebarSlide) { | |||
| $html.addClass(CLASS_NAME_CONTROL_SIDEBAR_ANIMATE) | |||
| $body.removeClass(CLASS_NAME_CONTROL_SIDEBAR_SLIDE).delay(300).queue(function () { | |||
| $(target).hide() | |||
| $html.removeClass(CLASS_NAME_CONTROL_SIDEBAR_ANIMATE) | |||
| $(this).dequeue() | |||
| }) | |||
| } else { | |||
| $body.removeClass(CLASS_NAME_CONTROL_SIDEBAR_OPEN) | |||
| } | |||
| $(this._element).trigger($.Event(EVENT_COLLAPSED)) | |||
| } | |||
| $(this._element).trigger($.Event(EVENT_EXPANDED)) | |||
| } | |||
| show() { | |||
| const $body = $('body') | |||
| const $html = $('html') | |||
| // Collapse the control sidebar | |||
| if (this._config.controlsidebarSlide) { | |||
| $html.addClass(CLASS_NAME_CONTROL_SIDEBAR_ANIMATE) | |||
| $(this._config.target).show().delay(10).queue(function () { | |||
| $body.addClass(CLASS_NAME_CONTROL_SIDEBAR_SLIDE).delay(300).queue(function () { | |||
| $html.removeClass(CLASS_NAME_CONTROL_SIDEBAR_ANIMATE) | |||
| $(this).dequeue() | |||
| }) | |||
| $(this).dequeue() | |||
| }) | |||
| } else { | |||
| $body.addClass(CLASS_NAME_CONTROL_SIDEBAR_OPEN) | |||
| } | |||
| toggle() { | |||
| const $body = $('body') | |||
| const shouldClose = $body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_OPEN) || | |||
| $body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_SLIDE) | |||
| this._fixHeight() | |||
| this._fixScrollHeight() | |||
| if (shouldClose) { | |||
| // Close the control sidebar | |||
| this.collapse() | |||
| } else { | |||
| // Open the control sidebar | |||
| this.show() | |||
| $(this._element).trigger($.Event(EVENT_EXPANDED)) | |||
| } | |||
| } | |||
| // Private | |||
| // Private | |||
| _init() { | |||
| const $body = $('body') | |||
| const shouldNotHideAll = $body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_OPEN) || | |||
| $body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_SLIDE) | |||
| toggle() { | |||
| const $body = $('body') | |||
| const shouldClose = $body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_OPEN) || | |||
| $body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_SLIDE) | |||
| if (shouldNotHideAll) { | |||
| $(SELECTOR_CONTROL_SIDEBAR).not(this._config.target).hide() | |||
| $(this._config.target).css('display', 'block') | |||
| } else { | |||
| $(SELECTOR_CONTROL_SIDEBAR).hide() | |||
| if (shouldClose) { | |||
| // Close the control sidebar | |||
| this.collapse() | |||
| } else { | |||
| // Open the control sidebar | |||
| this.show() | |||
| } | |||
| } | |||
| this._fixHeight() | |||
| this._fixScrollHeight() | |||
| _init() { | |||
| const $body = $('body') | |||
| const shouldNotHideAll = $body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_OPEN) || | |||
| $body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_SLIDE) | |||
| $(window).resize(() => { | |||
| this._fixHeight() | |||
| this._fixScrollHeight() | |||
| }) | |||
| $(window).scroll(() => { | |||
| const $body = $('body') | |||
| const shouldFixHeight = $body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_OPEN) || | |||
| $body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_SLIDE) | |||
| if (shouldNotHideAll) { | |||
| $(SELECTOR_CONTROL_SIDEBAR).not(this._config.target).hide() | |||
| $(this._config.target).css('display', 'block') | |||
| } else { | |||
| $(SELECTOR_CONTROL_SIDEBAR).hide() | |||
| } | |||
| if (shouldFixHeight) { | |||
| this._fixHeight() | |||
| this._fixScrollHeight() | |||
| } | |||
| }) | |||
| } | |||
| _isNavbarFixed() { | |||
| const $body = $('body') | |||
| return ( | |||
| $body.hasClass(CLASS_NAME_NAVBAR_FIXED) || | |||
| $body.hasClass(CLASS_NAME_NAVBAR_SM_FIXED) || | |||
| $body.hasClass(CLASS_NAME_NAVBAR_MD_FIXED) || | |||
| $body.hasClass(CLASS_NAME_NAVBAR_LG_FIXED) || | |||
| $body.hasClass(CLASS_NAME_NAVBAR_XL_FIXED) | |||
| ) | |||
| } | |||
| _isFooterFixed() { | |||
| const $body = $('body') | |||
| return ( | |||
| $body.hasClass(CLASS_NAME_FOOTER_FIXED) || | |||
| $body.hasClass(CLASS_NAME_FOOTER_SM_FIXED) || | |||
| $body.hasClass(CLASS_NAME_FOOTER_MD_FIXED) || | |||
| $body.hasClass(CLASS_NAME_FOOTER_LG_FIXED) || | |||
| $body.hasClass(CLASS_NAME_FOOTER_XL_FIXED) | |||
| ) | |||
| } | |||
| _fixScrollHeight() { | |||
| const $body = $('body') | |||
| const $controlSidebar = $(this._config.target) | |||
| if (!$body.hasClass(CLASS_NAME_LAYOUT_FIXED)) { | |||
| return | |||
| } | |||
| const heights = { | |||
| scroll: $(document).height(), | |||
| window: $(window).height(), | |||
| header: $(SELECTOR_HEADER).outerHeight(), | |||
| footer: $(SELECTOR_FOOTER).outerHeight() | |||
| } | |||
| const positions = { | |||
| bottom: Math.abs((heights.window + $(window).scrollTop()) - heights.scroll), | |||
| top: $(window).scrollTop() | |||
| } | |||
| $(window).resize(() => { | |||
| this._fixHeight() | |||
| this._fixScrollHeight() | |||
| }) | |||
| const navbarFixed = this._isNavbarFixed() && $(SELECTOR_HEADER).css('position') === 'fixed' | |||
| const footerFixed = this._isFooterFixed() && $(SELECTOR_FOOTER).css('position') === 'fixed' | |||
| const $controlsidebarContent = $(`${this._config.target}, ${this._config.target} ${SELECTOR_CONTROL_SIDEBAR_CONTENT}`) | |||
| if (positions.top === 0 && positions.bottom === 0) { | |||
| $controlSidebar.css({ | |||
| bottom: heights.footer, | |||
| top: heights.header | |||
| }) | |||
| $controlsidebarContent.css('height', heights.window - (heights.header + heights.footer)) | |||
| } else if (positions.bottom <= heights.footer) { | |||
| if (footerFixed === false) { | |||
| const top = heights.header - positions.top | |||
| $controlSidebar.css('bottom', heights.footer - positions.bottom).css('top', top >= 0 ? top : 0) | |||
| $controlsidebarContent.css('height', heights.window - (heights.footer - positions.bottom)) | |||
| } else { | |||
| $controlSidebar.css('bottom', heights.footer) | |||
| } | |||
| } else if (positions.top <= heights.header) { | |||
| if (navbarFixed === false) { | |||
| $controlSidebar.css('top', heights.header - positions.top) | |||
| $controlsidebarContent.css('height', heights.window - (heights.header - positions.top)) | |||
| } else { | |||
| $controlSidebar.css('top', heights.header) | |||
| } | |||
| } else if (navbarFixed === false) { | |||
| $controlSidebar.css('top', 0) | |||
| $controlsidebarContent.css('height', heights.window) | |||
| } else { | |||
| $controlSidebar.css('top', heights.header) | |||
| } | |||
| $(window).scroll(() => { | |||
| const $body = $('body') | |||
| const shouldFixHeight = $body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_OPEN) || | |||
| $body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_SLIDE) | |||
| if (footerFixed && navbarFixed) { | |||
| $controlsidebarContent.css('height', '100%') | |||
| $controlSidebar.css('height', '') | |||
| } else if (footerFixed || navbarFixed) { | |||
| $controlsidebarContent.css('height', '100%') | |||
| $controlsidebarContent.css('height', '') | |||
| if (shouldFixHeight) { | |||
| this._fixScrollHeight() | |||
| } | |||
| }) | |||
| } | |||
| } | |||
| _fixHeight() { | |||
| const $body = $('body') | |||
| const $controlSidebar = $(`${this._config.target} ${SELECTOR_CONTROL_SIDEBAR_CONTENT}`) | |||
| if (!$body.hasClass(CLASS_NAME_LAYOUT_FIXED)) { | |||
| $controlSidebar.attr('style', '') | |||
| return | |||
| _isNavbarFixed() { | |||
| const $body = $('body') | |||
| return ( | |||
| $body.hasClass(CLASS_NAME_NAVBAR_FIXED) || | |||
| $body.hasClass(CLASS_NAME_NAVBAR_SM_FIXED) || | |||
| $body.hasClass(CLASS_NAME_NAVBAR_MD_FIXED) || | |||
| $body.hasClass(CLASS_NAME_NAVBAR_LG_FIXED) || | |||
| $body.hasClass(CLASS_NAME_NAVBAR_XL_FIXED) | |||
| ) | |||
| } | |||
| const heights = { | |||
| window: $(window).height(), | |||
| header: $(SELECTOR_HEADER).outerHeight(), | |||
| footer: $(SELECTOR_FOOTER).outerHeight() | |||
| _isFooterFixed() { | |||
| const $body = $('body') | |||
| return ( | |||
| $body.hasClass(CLASS_NAME_FOOTER_FIXED) || | |||
| $body.hasClass(CLASS_NAME_FOOTER_SM_FIXED) || | |||
| $body.hasClass(CLASS_NAME_FOOTER_MD_FIXED) || | |||
| $body.hasClass(CLASS_NAME_FOOTER_LG_FIXED) || | |||
| $body.hasClass(CLASS_NAME_FOOTER_XL_FIXED) | |||
| ) | |||
| } | |||
| let sidebarHeight = heights.window - heights.header | |||
| _fixScrollHeight() { | |||
| const $body = $('body') | |||
| const $controlSidebar = $(this._config.target) | |||
| if (this._isFooterFixed() && $(SELECTOR_FOOTER).css('position') === 'fixed') { | |||
| sidebarHeight = heights.window - heights.header - heights.footer | |||
| } | |||
| if (!$body.hasClass(CLASS_NAME_LAYOUT_FIXED)) { | |||
| return | |||
| } | |||
| $controlSidebar.css('height', sidebarHeight) | |||
| const heights = { | |||
| scroll: $(document).height(), | |||
| window: $(window).height(), | |||
| header: $(SELECTOR_HEADER).outerHeight(), | |||
| footer: $(SELECTOR_FOOTER).outerHeight() | |||
| } | |||
| const positions = { | |||
| bottom: Math.abs((heights.window + $(window).scrollTop()) - heights.scroll), | |||
| top: $(window).scrollTop() | |||
| } | |||
| const navbarFixed = this._isNavbarFixed() && $(SELECTOR_HEADER).css('position') === 'fixed' | |||
| const footerFixed = this._isFooterFixed() && $(SELECTOR_FOOTER).css('position') === 'fixed' | |||
| const $controlsidebarContent = $(`${this._config.target}, ${this._config.target} ${SELECTOR_CONTROL_SIDEBAR_CONTENT}`) | |||
| if (positions.top === 0 && positions.bottom === 0) { | |||
| $controlSidebar.css({ | |||
| bottom: heights.footer, | |||
| top: heights.header | |||
| }) | |||
| $controlsidebarContent.css('height', heights.window - (heights.header + heights.footer)) | |||
| } else if (positions.bottom <= heights.footer) { | |||
| if (footerFixed === false) { | |||
| const top = heights.header - positions.top | |||
| $controlSidebar.css('bottom', heights.footer - positions.bottom).css('top', top >= 0 ? top : 0) | |||
| $controlsidebarContent.css('height', heights.window - (heights.footer - positions.bottom)) | |||
| } else { | |||
| $controlSidebar.css('bottom', heights.footer) | |||
| } | |||
| } else if (positions.top <= heights.header) { | |||
| if (navbarFixed === false) { | |||
| $controlSidebar.css('top', heights.header - positions.top) | |||
| $controlsidebarContent.css('height', heights.window - (heights.header - positions.top)) | |||
| } else { | |||
| $controlSidebar.css('top', heights.header) | |||
| } | |||
| } else if (navbarFixed === false) { | |||
| $controlSidebar.css('top', 0) | |||
| $controlsidebarContent.css('height', heights.window) | |||
| } else { | |||
| $controlSidebar.css('top', heights.header) | |||
| } | |||
| if (typeof $.fn.overlayScrollbars !== 'undefined') { | |||
| $controlSidebar.overlayScrollbars({ | |||
| className: this._config.scrollbarTheme, | |||
| sizeAutoCapable: true, | |||
| scrollbars: { | |||
| autoHide: this._config.scrollbarAutoHide, | |||
| clickScrolling: true | |||
| if (footerFixed && navbarFixed) { | |||
| $controlsidebarContent.css('height', '100%') | |||
| $controlSidebar.css('height', '') | |||
| } else if (footerFixed || navbarFixed) { | |||
| $controlsidebarContent.css('height', '100%') | |||
| $controlsidebarContent.css('height', '') | |||
| } | |||
| }) | |||
| } | |||
| } | |||
| // Static | |||
| // Static | |||
| static _jQueryInterface(operation) { | |||
| return this.each(function () { | |||
| let data = $(this).data(DATA_KEY) | |||
| const _options = $.extend({}, Default, $(this).data()) | |||
| _fixHeight() { | |||
| const $body = $('body') | |||
| const $controlSidebar = $(`${this._config.target} ${SELECTOR_CONTROL_SIDEBAR_CONTENT}`) | |||
| if (!data) { | |||
| data = new ControlSidebar(this, _options) | |||
| $(this).data(DATA_KEY, data) | |||
| } | |||
| if (!$body.hasClass(CLASS_NAME_LAYOUT_FIXED)) { | |||
| $controlSidebar.attr('style', '') | |||
| return | |||
| } | |||
| const heights = { | |||
| window: $(window).height(), | |||
| header: $(SELECTOR_HEADER).outerHeight(), | |||
| footer: $(SELECTOR_FOOTER).outerHeight() | |||
| } | |||
| if (data[operation] === 'undefined') { | |||
| throw new Error(`${operation} is not a function`) | |||
| } | |||
| let sidebarHeight = heights.window - heights.header | |||
| data[operation]() | |||
| }) | |||
| } | |||
| if (this._isFooterFixed() && $(SELECTOR_FOOTER).css('position') === 'fixed') { | |||
| sidebarHeight = heights.window - heights.header - heights.footer | |||
| } | |||
| $controlSidebar.css('height', sidebarHeight) | |||
| if (typeof $.fn.overlayScrollbars !== 'undefined') { | |||
| $controlSidebar.overlayScrollbars({ | |||
| className: this._config.scrollbarTheme, | |||
| sizeAutoCapable: true, | |||
| scrollbars: { | |||
| autoHide: this._config.scrollbarAutoHide, | |||
| clickScrolling: true | |||
| } | |||
| }) | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| @@ -298,13 +298,13 @@ class ControlSidebar { | |||
| * ==================================================== | |||
| */ | |||
| $(document).on('click', SELECTOR_DATA_TOGGLE, function (event) { | |||
| event.preventDefault() | |||
| event.preventDefault() | |||
| ControlSidebar._jQueryInterface.call($(this), 'toggle') | |||
| ControlSidebar._jQueryInterface.call($(this), 'toggle') | |||
| }) | |||
| $(document).ready(() => { | |||
| ControlSidebar._jQueryInterface.call($(SELECTOR_DATA_TOGGLE), '_init') | |||
| ControlSidebar._jQueryInterface.call($(SELECTOR_DATA_TOGGLE), '_init') | |||
| }) | |||
| /** | |||
| @@ -315,8 +315,8 @@ $(document).ready(() => { | |||
| $.fn[NAME] = ControlSidebar._jQueryInterface | |||
| $.fn[NAME].Constructor = ControlSidebar | |||
| $.fn[NAME].noConflict = function () { | |||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||
| return ControlSidebar._jQueryInterface | |||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||
| return ControlSidebar._jQueryInterface | |||
| } | |||
| export default ControlSidebar | |||
| @@ -30,29 +30,29 @@ const CLASS_NAME_DIRECT_CHAT_OPEN = 'direct-chat-contacts-open' | |||
| */ | |||
| class DirectChat { | |||
| constructor(element) { | |||
| this._element = element | |||
| } | |||
| constructor(element) { | |||
| this._element = element | |||
| } | |||
| toggle() { | |||
| $(this._element).parents(SELECTOR_DIRECT_CHAT).first().toggleClass(CLASS_NAME_DIRECT_CHAT_OPEN) | |||
| $(this._element).trigger($.Event(EVENT_TOGGLED)) | |||
| } | |||
| static _jQueryInterface(config) { | |||
| return this.each(function () { | |||
| let data = $(this).data(DATA_KEY) | |||
| // Static | |||
| if (!data) { | |||
| data = new DirectChat($(this)) | |||
| $(this).data(DATA_KEY, data) | |||
| } | |||
| static _jQueryInterface(config) { | |||
| return this.each(function () { | |||
| let data = $(this).data(DATA_KEY) | |||
| data[config]() | |||
| }) | |||
| } | |||
| if (!data) { | |||
| data = new DirectChat($(this)) | |||
| $(this).data(DATA_KEY, data) | |||
| } | |||
| // Static | |||
| data[config]() | |||
| }) | |||
| } | |||
| toggle() { | |||
| $(this._element).parents(SELECTOR_DIRECT_CHAT).first().toggleClass(CLASS_NAME_DIRECT_CHAT_OPEN) | |||
| $(this._element).trigger($.Event(EVENT_TOGGLED)) | |||
| } | |||
| } | |||
| /** | |||
| @@ -62,11 +62,11 @@ class DirectChat { | |||
| */ | |||
| $(document).on('click', SELECTOR_DATA_TOGGLE, function (event) { | |||
| if (event) { | |||
| event.preventDefault() | |||
| } | |||
| if (event) { | |||
| event.preventDefault() | |||
| } | |||
| DirectChat._jQueryInterface.call($(this), 'toggle') | |||
| DirectChat._jQueryInterface.call($(this), 'toggle') | |||
| }) | |||
| /** | |||
| @@ -77,8 +77,8 @@ $(document).on('click', SELECTOR_DATA_TOGGLE, function (event) { | |||
| $.fn[NAME] = DirectChat._jQueryInterface | |||
| $.fn[NAME].Constructor = DirectChat | |||
| $.fn[NAME].noConflict = function () { | |||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||
| return DirectChat._jQueryInterface | |||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||
| return DirectChat._jQueryInterface | |||
| } | |||
| export default DirectChat | |||
| @@ -33,78 +33,78 @@ const Default = {} | |||
| */ | |||
| class Dropdown { | |||
| constructor(element, config) { | |||
| this._config = config | |||
| this._element = element | |||
| } | |||
| // Public | |||
| toggleSubmenu() { | |||
| this._element.siblings().show().toggleClass('show') | |||
| if (!this._element.next().hasClass('show')) { | |||
| this._element.parents(SELECTOR_DROPDOWN_MENU).first().find('.show').removeClass('show').hide() | |||
| constructor(element, config) { | |||
| this._config = config | |||
| this._element = element | |||
| } | |||
| this._element.parents('li.nav-item.dropdown.show').on('hidden.bs.dropdown', () => { | |||
| $('.dropdown-submenu .show').removeClass('show').hide() | |||
| }) | |||
| } | |||
| // Public | |||
| fixPosition() { | |||
| const $element = $(SELECTOR_DROPDOWN_MENU_ACTIVE) | |||
| static _jQueryInterface(config) { | |||
| return this.each(function () { | |||
| let data = $(this).data(DATA_KEY) | |||
| const _config = $.extend({}, Default, $(this).data()) | |||
| if ($element.length === 0) { | |||
| return | |||
| } | |||
| if (!data) { | |||
| data = new Dropdown($(this), _config) | |||
| $(this).data(DATA_KEY, data) | |||
| } | |||
| if ($element.hasClass(CLASS_NAME_DROPDOWN_RIGHT)) { | |||
| $element.css({ | |||
| left: 'inherit', | |||
| right: 0 | |||
| }) | |||
| } else { | |||
| $element.css({ | |||
| left: 0, | |||
| right: 'inherit' | |||
| }) | |||
| if (config === 'toggleSubmenu' || config === 'fixPosition') { | |||
| data[config]() | |||
| } | |||
| }) | |||
| } | |||
| const offset = $element.offset() | |||
| const width = $element.width() | |||
| const visiblePart = $(window).width() - offset.left | |||
| if (offset.left < 0) { | |||
| $element.css({ | |||
| left: 'inherit', | |||
| right: offset.left - 5 | |||
| }) | |||
| } else if (visiblePart < width) { | |||
| $element.css({ | |||
| left: 'inherit', | |||
| right: 0 | |||
| }) | |||
| } | |||
| } | |||
| toggleSubmenu() { | |||
| this._element.siblings().show().toggleClass('show') | |||
| // Static | |||
| if (!this._element.next().hasClass('show')) { | |||
| this._element.parents(SELECTOR_DROPDOWN_MENU).first().find('.show').removeClass('show').hide() | |||
| } | |||
| static _jQueryInterface(config) { | |||
| return this.each(function () { | |||
| let data = $(this).data(DATA_KEY) | |||
| const _config = $.extend({}, Default, $(this).data()) | |||
| if (!data) { | |||
| data = new Dropdown($(this), _config) | |||
| $(this).data(DATA_KEY, data) | |||
| } | |||
| this._element.parents('li.nav-item.dropdown.show').on('hidden.bs.dropdown', () => { | |||
| $('.dropdown-submenu .show').removeClass('show').hide() | |||
| }) | |||
| } | |||
| if (config === 'toggleSubmenu' || config === 'fixPosition') { | |||
| data[config]() | |||
| } | |||
| }) | |||
| } | |||
| // Static | |||
| fixPosition() { | |||
| const $element = $(SELECTOR_DROPDOWN_MENU_ACTIVE) | |||
| if ($element.length === 0) { | |||
| return | |||
| } | |||
| if ($element.hasClass(CLASS_NAME_DROPDOWN_RIGHT)) { | |||
| $element.css({ | |||
| left: 'inherit', | |||
| right: 0 | |||
| }) | |||
| } else { | |||
| $element.css({ | |||
| left: 0, | |||
| right: 'inherit' | |||
| }) | |||
| } | |||
| const offset = $element.offset() | |||
| const width = $element.width() | |||
| const visiblePart = $(window).width() - offset.left | |||
| if (offset.left < 0) { | |||
| $element.css({ | |||
| left: 'inherit', | |||
| right: offset.left - 5 | |||
| }) | |||
| } else if (visiblePart < width) { | |||
| $element.css({ | |||
| left: 'inherit', | |||
| right: 0 | |||
| }) | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| @@ -113,22 +113,22 @@ class Dropdown { | |||
| */ | |||
| $(`${SELECTOR_DROPDOWN_MENU} ${SELECTOR_DROPDOWN_TOGGLE}`).on('click', function (event) { | |||
| event.preventDefault() | |||
| event.stopPropagation() | |||
| event.preventDefault() | |||
| event.stopPropagation() | |||
| Dropdown._jQueryInterface.call($(this), 'toggleSubmenu') | |||
| Dropdown._jQueryInterface.call($(this), 'toggleSubmenu') | |||
| }) | |||
| $(`${SELECTOR_NAVBAR} ${SELECTOR_DROPDOWN_TOGGLE}`).on('click', event => { | |||
| event.preventDefault() | |||
| event.preventDefault() | |||
| if ($(event.target).parent().hasClass(CLASS_NAME_DROPDOWN_SUBMENU)) { | |||
| return | |||
| } | |||
| if ($(event.target).parent().hasClass(CLASS_NAME_DROPDOWN_SUBMENU)) { | |||
| return | |||
| } | |||
| setTimeout(function () { | |||
| Dropdown._jQueryInterface.call($(this), 'fixPosition') | |||
| }, 1) | |||
| setTimeout(function () { | |||
| Dropdown._jQueryInterface.call($(this), 'fixPosition') | |||
| }, 1) | |||
| }) | |||
| /** | |||
| @@ -139,8 +139,8 @@ $(`${SELECTOR_NAVBAR} ${SELECTOR_DROPDOWN_TOGGLE}`).on('click', event => { | |||
| $.fn[NAME] = Dropdown._jQueryInterface | |||
| $.fn[NAME].Constructor = Dropdown | |||
| $.fn[NAME].noConflict = function () { | |||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||
| return Dropdown._jQueryInterface | |||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||
| return Dropdown._jQueryInterface | |||
| } | |||
| export default Dropdown | |||
| @@ -8,9 +8,9 @@ | |||
| import $ from 'jquery' | |||
| /** | |||
| * Constants | |||
| * ==================================================== | |||
| */ | |||
| * Constants | |||
| * ==================================================== | |||
| */ | |||
| const NAME = 'ExpandableTable' | |||
| const DATA_KEY = 'lte.expandableTable' | |||
| @@ -26,91 +26,91 @@ const SELECTOR_DATA_TOGGLE = '[data-widget="expandable-table"]' | |||
| const SELECTOR_ARIA_ATTR = 'aria-expanded' | |||
| /** | |||
| * Class Definition | |||
| * ==================================================== | |||
| */ | |||
| * Class Definition | |||
| * ==================================================== | |||
| */ | |||
| class ExpandableTable { | |||
| constructor(element, options) { | |||
| this._options = options | |||
| this._element = element | |||
| } | |||
| // Public | |||
| init() { | |||
| $(SELECTOR_DATA_TOGGLE).each((_, $header) => { | |||
| const $type = $($header).attr(SELECTOR_ARIA_ATTR) | |||
| const $body = $($header).next(SELECTOR_EXPANDABLE_BODY).children().first().children() | |||
| if ($type === 'true') { | |||
| $body.show() | |||
| } else if ($type === 'false') { | |||
| $body.hide() | |||
| $body.parent().parent().addClass('d-none') | |||
| } | |||
| }) | |||
| } | |||
| toggleRow() { | |||
| const $element = this._element | |||
| const time = 500 | |||
| const $type = $element.attr(SELECTOR_ARIA_ATTR) | |||
| const $body = $element.next(SELECTOR_EXPANDABLE_BODY).children().first().children() | |||
| $body.stop() | |||
| if ($type === 'true') { | |||
| $body.slideUp(time, () => { | |||
| $element.next(SELECTOR_EXPANDABLE_BODY).addClass('d-none') | |||
| }) | |||
| $element.attr(SELECTOR_ARIA_ATTR, 'false') | |||
| $element.trigger($.Event(EVENT_COLLAPSED)) | |||
| } else if ($type === 'false') { | |||
| $element.next(SELECTOR_EXPANDABLE_BODY).removeClass('d-none') | |||
| $body.slideDown(time) | |||
| $element.attr(SELECTOR_ARIA_ATTR, 'true') | |||
| $element.trigger($.Event(EVENT_EXPANDED)) | |||
| constructor(element, options) { | |||
| this._options = options | |||
| this._element = element | |||
| } | |||
| } | |||
| // Static | |||
| // Public | |||
| static _jQueryInterface(operation) { | |||
| return this.each(function () { | |||
| let data = $(this).data(DATA_KEY) | |||
| static _jQueryInterface(operation) { | |||
| return this.each(function () { | |||
| let data = $(this).data(DATA_KEY) | |||
| if (!data) { | |||
| data = new ExpandableTable($(this)) | |||
| $(this).data(DATA_KEY, data) | |||
| } | |||
| if (!data) { | |||
| data = new ExpandableTable($(this)) | |||
| $(this).data(DATA_KEY, data) | |||
| } | |||
| if (typeof operation === 'string' && /init|toggleRow/.test(operation)) { | |||
| data[operation]() | |||
| } | |||
| }) | |||
| } | |||
| if (typeof operation === 'string' && /init|toggleRow/.test(operation)) { | |||
| data[operation]() | |||
| } | |||
| }) | |||
| } | |||
| init() { | |||
| $(SELECTOR_DATA_TOGGLE).each((_, $header) => { | |||
| const $type = $($header).attr(SELECTOR_ARIA_ATTR) | |||
| const $body = $($header).next(SELECTOR_EXPANDABLE_BODY).children().first().children() | |||
| if ($type === 'true') { | |||
| $body.show() | |||
| } else if ($type === 'false') { | |||
| $body.hide() | |||
| $body.parent().parent().addClass('d-none') | |||
| } | |||
| }) | |||
| } | |||
| // Static | |||
| toggleRow() { | |||
| const $element = this._element | |||
| const time = 500 | |||
| const $type = $element.attr(SELECTOR_ARIA_ATTR) | |||
| const $body = $element.next(SELECTOR_EXPANDABLE_BODY).children().first().children() | |||
| $body.stop() | |||
| if ($type === 'true') { | |||
| $body.slideUp(time, () => { | |||
| $element.next(SELECTOR_EXPANDABLE_BODY).addClass('d-none') | |||
| }) | |||
| $element.attr(SELECTOR_ARIA_ATTR, 'false') | |||
| $element.trigger($.Event(EVENT_COLLAPSED)) | |||
| } else if ($type === 'false') { | |||
| $element.next(SELECTOR_EXPANDABLE_BODY).removeClass('d-none') | |||
| $body.slideDown(time) | |||
| $element.attr(SELECTOR_ARIA_ATTR, 'true') | |||
| $element.trigger($.Event(EVENT_EXPANDED)) | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| * Data API | |||
| * ==================================================== | |||
| */ | |||
| * Data API | |||
| * ==================================================== | |||
| */ | |||
| $(SELECTOR_TABLE).ready(function () { | |||
| ExpandableTable._jQueryInterface.call($(this), 'init') | |||
| ExpandableTable._jQueryInterface.call($(this), 'init') | |||
| }) | |||
| $(document).on('click', SELECTOR_DATA_TOGGLE, function () { | |||
| ExpandableTable._jQueryInterface.call($(this), 'toggleRow') | |||
| ExpandableTable._jQueryInterface.call($(this), 'toggleRow') | |||
| }) | |||
| /** | |||
| * jQuery API | |||
| * ==================================================== | |||
| */ | |||
| * jQuery API | |||
| * ==================================================== | |||
| */ | |||
| $.fn[NAME] = ExpandableTable._jQueryInterface | |||
| $.fn[NAME].Constructor = ExpandableTable | |||
| $.fn[NAME].noConflict = function () { | |||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||
| return ExpandableTable._jQueryInterface | |||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||
| return ExpandableTable._jQueryInterface | |||
| } | |||
| export default ExpandableTable | |||
| @@ -20,8 +20,8 @@ const SELECTOR_DATA_WIDGET = '[data-widget="fullscreen"]' | |||
| const SELECTOR_ICON = `${SELECTOR_DATA_WIDGET} i` | |||
| const Default = { | |||
| minimizeIcon: 'fa-compress-arrows-alt', | |||
| maximizeIcon: 'fa-expand-arrows-alt' | |||
| minimizeIcon: 'fa-compress-arrows-alt', | |||
| maximizeIcon: 'fa-expand-arrows-alt' | |||
| } | |||
| /** | |||
| @@ -30,76 +30,76 @@ const Default = { | |||
| */ | |||
| class Fullscreen { | |||
| constructor(_element, _options) { | |||
| this.element = _element | |||
| this.options = $.extend({}, Default, _options) | |||
| } | |||
| // Public | |||
| toggle() { | |||
| if (document.fullscreenElement || | |||
| document.mozFullScreenElement || | |||
| document.webkitFullscreenElement || | |||
| document.msFullscreenElement) { | |||
| this.windowed() | |||
| } else { | |||
| this.fullscreen() | |||
| } | |||
| } | |||
| fullscreen() { | |||
| if (document.documentElement.requestFullscreen) { | |||
| document.documentElement.requestFullscreen() | |||
| } else if (document.documentElement.webkitRequestFullscreen) { | |||
| document.documentElement.webkitRequestFullscreen() | |||
| } else if (document.documentElement.msRequestFullscreen) { | |||
| document.documentElement.msRequestFullscreen() | |||
| constructor(_element, _options) { | |||
| this.element = _element | |||
| this.options = $.extend({}, Default, _options) | |||
| } | |||
| $(SELECTOR_ICON).removeClass(this.options.maximizeIcon).addClass(this.options.minimizeIcon) | |||
| } | |||
| // Public | |||
| windowed() { | |||
| if (document.exitFullscreen) { | |||
| document.exitFullscreen() | |||
| } else if (document.webkitExitFullscreen) { | |||
| document.webkitExitFullscreen() | |||
| } else if (document.msExitFullscreen) { | |||
| document.msExitFullscreen() | |||
| } | |||
| static _jQueryInterface(config) { | |||
| let data = $(this).data(DATA_KEY) | |||
| $(SELECTOR_ICON).removeClass(this.options.minimizeIcon).addClass(this.options.maximizeIcon) | |||
| } | |||
| if (!data) { | |||
| data = $(this).data() | |||
| } | |||
| // Static | |||
| const _options = $.extend({}, Default, typeof config === 'object' ? config : data) | |||
| const plugin = new Fullscreen($(this), _options) | |||
| static _jQueryInterface(config) { | |||
| let data = $(this).data(DATA_KEY) | |||
| $(this).data(DATA_KEY, typeof config === 'object' ? config : data) | |||
| if (!data) { | |||
| data = $(this).data() | |||
| if (typeof config === 'string' && /toggle|fullscreen|windowed/.test(config)) { | |||
| plugin[config]() | |||
| } else { | |||
| plugin.init() | |||
| } | |||
| } | |||
| const _options = $.extend({}, Default, typeof config === 'object' ? config : data) | |||
| const plugin = new Fullscreen($(this), _options) | |||
| toggle() { | |||
| if (document.fullscreenElement || | |||
| document.mozFullScreenElement || | |||
| document.webkitFullscreenElement || | |||
| document.msFullscreenElement) { | |||
| this.windowed() | |||
| } else { | |||
| this.fullscreen() | |||
| } | |||
| } | |||
| $(this).data(DATA_KEY, typeof config === 'object' ? config : data) | |||
| fullscreen() { | |||
| if (document.documentElement.requestFullscreen) { | |||
| document.documentElement.requestFullscreen() | |||
| } else if (document.documentElement.webkitRequestFullscreen) { | |||
| document.documentElement.webkitRequestFullscreen() | |||
| } else if (document.documentElement.msRequestFullscreen) { | |||
| document.documentElement.msRequestFullscreen() | |||
| } | |||
| if (typeof config === 'string' && /toggle|fullscreen|windowed/.test(config)) { | |||
| plugin[config]() | |||
| } else { | |||
| plugin.init() | |||
| $(SELECTOR_ICON).removeClass(this.options.maximizeIcon).addClass(this.options.minimizeIcon) | |||
| } | |||
| // Static | |||
| windowed() { | |||
| if (document.exitFullscreen) { | |||
| document.exitFullscreen() | |||
| } else if (document.webkitExitFullscreen) { | |||
| document.webkitExitFullscreen() | |||
| } else if (document.msExitFullscreen) { | |||
| document.msExitFullscreen() | |||
| } | |||
| $(SELECTOR_ICON).removeClass(this.options.minimizeIcon).addClass(this.options.maximizeIcon) | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| * Data API | |||
| * ==================================================== | |||
| */ | |||
| * Data API | |||
| * ==================================================== | |||
| */ | |||
| $(document).on('click', SELECTOR_DATA_WIDGET, function () { | |||
| Fullscreen._jQueryInterface.call($(this), 'toggle') | |||
| Fullscreen._jQueryInterface.call($(this), 'toggle') | |||
| }) | |||
| /** | |||
| @@ -110,8 +110,8 @@ $(document).on('click', SELECTOR_DATA_WIDGET, function () { | |||
| $.fn[NAME] = Fullscreen._jQueryInterface | |||
| $.fn[NAME].Constructor = Fullscreen | |||
| $.fn[NAME].noConflict = function () { | |||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||
| return Fullscreen._jQueryInterface | |||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||
| return Fullscreen._jQueryInterface | |||
| } | |||
| export default Fullscreen | |||
| @@ -39,25 +39,25 @@ const CLASS_NAME_IFRAME_MODE = 'iframe-mode' | |||
| const CLASS_NAME_FULLSCREEN_MODE = 'iframe-mode-fullscreen' | |||
| const Default = { | |||
| onTabClick(item) { | |||
| return item | |||
| }, | |||
| onTabChanged(item) { | |||
| return item | |||
| }, | |||
| onTabCreated(item) { | |||
| return item | |||
| }, | |||
| autoIframeMode: true, | |||
| autoItemActive: true, | |||
| autoShowNewTab: true, | |||
| allowDuplicates: false, | |||
| loadingScreen: true, | |||
| useNavbarItems: true, | |||
| scrollOffset: 40, | |||
| scrollBehaviorSwap: false, | |||
| iconMaximize: 'fa-expand', | |||
| iconMinimize: 'fa-compress' | |||
| onTabClick(item) { | |||
| return item | |||
| }, | |||
| onTabChanged(item) { | |||
| return item | |||
| }, | |||
| onTabCreated(item) { | |||
| return item | |||
| }, | |||
| autoIframeMode: true, | |||
| autoItemActive: true, | |||
| autoShowNewTab: true, | |||
| allowDuplicates: false, | |||
| loadingScreen: true, | |||
| useNavbarItems: true, | |||
| scrollOffset: 40, | |||
| scrollBehaviorSwap: false, | |||
| iconMaximize: 'fa-expand', | |||
| iconMinimize: 'fa-compress' | |||
| } | |||
| /** | |||
| @@ -66,327 +66,327 @@ const Default = { | |||
| */ | |||
| class IFrame { | |||
| constructor(element, config) { | |||
| this._config = config | |||
| this._element = element | |||
| constructor(element, config) { | |||
| this._config = config | |||
| this._element = element | |||
| this._init() | |||
| } | |||
| this._init() | |||
| } | |||
| // Public | |||
| // Public | |||
| onTabClick(item) { | |||
| this._config.onTabClick(item) | |||
| } | |||
| static _jQueryInterface(operation, ...args) { | |||
| let data = $(this).data(DATA_KEY) | |||
| const _options = $.extend({}, Default, $(this).data()) | |||
| onTabChanged(item) { | |||
| this._config.onTabChanged(item) | |||
| } | |||
| if (!data) { | |||
| data = new IFrame(this, _options) | |||
| $(this).data(DATA_KEY, data) | |||
| } | |||
| onTabCreated(item) { | |||
| this._config.onTabCreated(item) | |||
| } | |||
| if (typeof operation === 'string' && /createTab|openTabSidebar|switchTab|removeActiveTab/.test(operation)) { | |||
| data[operation](...args) | |||
| } | |||
| } | |||
| createTab(title, link, uniqueName, autoOpen) { | |||
| let tabId = `panel-${uniqueName}` | |||
| let navId = `tab-${uniqueName}` | |||
| onTabClick(item) { | |||
| this._config.onTabClick(item) | |||
| } | |||
| if (this._config.allowDuplicates) { | |||
| tabId += `-${Math.floor(Math.random() * 1000)}` | |||
| navId += `-${Math.floor(Math.random() * 1000)}` | |||
| onTabChanged(item) { | |||
| this._config.onTabChanged(item) | |||
| } | |||
| const newNavItem = `<li class="nav-item" role="presentation"><a href="#" class="btn-iframe-close" data-widget="iframe-close" data-type="only-this"><i class="fas fa-times"></i></a><a class="nav-link" data-toggle="row" id="${navId}" href="#${tabId}" role="tab" aria-controls="${tabId}" aria-selected="false">${title}</a></li>` | |||
| $(SELECTOR_TAB_NAVBAR_NAV).append(unescape(escape(newNavItem))) | |||
| onTabCreated(item) { | |||
| this._config.onTabCreated(item) | |||
| } | |||
| const newTabItem = `<div class="tab-pane fade" id="${tabId}" role="tabpanel" aria-labelledby="${navId}"><iframe src="${link}"></iframe></div>` | |||
| $(SELECTOR_TAB_CONTENT).append(unescape(escape(newTabItem))) | |||
| createTab(title, link, uniqueName, autoOpen) { | |||
| let tabId = `panel-${uniqueName}` | |||
| let navId = `tab-${uniqueName}` | |||
| if (this._config.allowDuplicates) { | |||
| tabId += `-${Math.floor(Math.random() * 1000)}` | |||
| navId += `-${Math.floor(Math.random() * 1000)}` | |||
| } | |||
| const newNavItem = `<li class="nav-item" role="presentation"><a href="#" class="btn-iframe-close" data-widget="iframe-close" data-type="only-this"><i class="fas fa-times"></i></a><a class="nav-link" data-toggle="row" id="${navId}" href="#${tabId}" role="tab" aria-controls="${tabId}" aria-selected="false">${title}</a></li>` | |||
| $(SELECTOR_TAB_NAVBAR_NAV).append(unescape(escape(newNavItem))) | |||
| const newTabItem = `<div class="tab-pane fade" id="${tabId}" role="tabpanel" aria-labelledby="${navId}"><iframe src="${link}"></iframe></div>` | |||
| $(SELECTOR_TAB_CONTENT).append(unescape(escape(newTabItem))) | |||
| if (autoOpen) { | |||
| if (this._config.loadingScreen) { | |||
| const $loadingScreen = $(SELECTOR_TAB_LOADING) | |||
| $loadingScreen.fadeIn() | |||
| $(`${tabId} iframe`).ready(() => { | |||
| if (typeof this._config.loadingScreen === 'number') { | |||
| this.switchTab(`#${navId}`) | |||
| setTimeout(() => { | |||
| $loadingScreen.fadeOut() | |||
| }, this._config.loadingScreen) | |||
| } else { | |||
| this.switchTab(`#${navId}`) | |||
| $loadingScreen.fadeOut() | |||
| } | |||
| }) | |||
| } else { | |||
| this.switchTab(`#${navId}`) | |||
| } | |||
| } | |||
| this.onTabCreated($(`#${navId}`)) | |||
| } | |||
| if (autoOpen) { | |||
| if (this._config.loadingScreen) { | |||
| const $loadingScreen = $(SELECTOR_TAB_LOADING) | |||
| $loadingScreen.fadeIn() | |||
| $(`${tabId} iframe`).ready(() => { | |||
| if (typeof this._config.loadingScreen === 'number') { | |||
| this.switchTab(`#${navId}`) | |||
| setTimeout(() => { | |||
| $loadingScreen.fadeOut() | |||
| }, this._config.loadingScreen) | |||
| } else { | |||
| this.switchTab(`#${navId}`) | |||
| $loadingScreen.fadeOut() | |||
| } | |||
| }) | |||
| } else { | |||
| this.switchTab(`#${navId}`) | |||
| } | |||
| openTabSidebar(item, autoOpen = this._config.autoShowNewTab) { | |||
| let $item = $(item).clone() | |||
| if ($item.attr('href') === undefined) { | |||
| $item = $(item).parent('a').clone() | |||
| } | |||
| $item.find('.right, .search-path').remove() | |||
| let title = $item.find('p').text() | |||
| if (title === '') { | |||
| title = $item.text() | |||
| } | |||
| const link = $item.attr('href') | |||
| if (link === '#' || link === '' || link === undefined) { | |||
| return | |||
| } | |||
| const uniqueName = link.replace('./', '').replace(/["&'./:=?[\]]/gi, '-').replace(/(--)/gi, '') | |||
| const navId = `tab-${uniqueName}` | |||
| if (!this._config.allowDuplicates && $(`#${navId}`).length > 0) { | |||
| return this.switchTab(`#${navId}`) | |||
| } | |||
| if ((!this._config.allowDuplicates && $(`#${navId}`).length === 0) || this._config.allowDuplicates) { | |||
| this.createTab(title, link, uniqueName, autoOpen) | |||
| } | |||
| } | |||
| this.onTabCreated($(`#${navId}`)) | |||
| } | |||
| switchTab(item) { | |||
| const $item = $(item) | |||
| const tabId = $item.attr('href') | |||
| openTabSidebar(item, autoOpen = this._config.autoShowNewTab) { | |||
| let $item = $(item).clone() | |||
| if ($item.attr('href') === undefined) { | |||
| $item = $(item).parent('a').clone() | |||
| } | |||
| $(SELECTOR_TAB_EMPTY).hide() | |||
| $(`${SELECTOR_TAB_NAVBAR_NAV} .active`).tab('dispose').removeClass('active') | |||
| this._fixHeight() | |||
| $item.tab('show') | |||
| $item.parents('li').addClass('active') | |||
| this.onTabChanged($item) | |||
| $item.find('.right, .search-path').remove() | |||
| let title = $item.find('p').text() | |||
| if (title === '') { | |||
| title = $item.text() | |||
| if (this._config.autoItemActive) { | |||
| this._setItemActive($(`${tabId} iframe`).attr('src')) | |||
| } | |||
| } | |||
| const link = $item.attr('href') | |||
| if (link === '#' || link === '' || link === undefined) { | |||
| return | |||
| removeActiveTab(type, element) { | |||
| if (type == 'all') { | |||
| $(SELECTOR_TAB_NAVBAR_NAV_ITEM).remove() | |||
| $(SELECTOR_TAB_PANE).remove() | |||
| $(SELECTOR_TAB_EMPTY).show() | |||
| } else if (type == 'all-other') { | |||
| $(`${SELECTOR_TAB_NAVBAR_NAV_ITEM}:not(.active)`).remove() | |||
| $(`${SELECTOR_TAB_PANE}:not(.active)`).remove() | |||
| } else if (type == 'only-this') { | |||
| const $navClose = $(element) | |||
| const $navItem = $navClose.parent('.nav-item') | |||
| const $navItemParent = $navItem.parent() | |||
| const navItemIndex = $navItem.index() | |||
| const tabId = $navClose.siblings('.nav-link').attr('aria-controls') | |||
| $navItem.remove() | |||
| $(`#${tabId}`).remove() | |||
| if ($(SELECTOR_TAB_CONTENT).children().length == $(`${SELECTOR_TAB_EMPTY}, ${SELECTOR_TAB_LOADING}`).length) { | |||
| $(SELECTOR_TAB_EMPTY).show() | |||
| } else { | |||
| const prevNavItemIndex = navItemIndex - 1 | |||
| this.switchTab($navItemParent.children().eq(prevNavItemIndex).find('a.nav-link')) | |||
| } | |||
| } else { | |||
| const $navItem = $(`${SELECTOR_TAB_NAVBAR_NAV_ITEM}.active`) | |||
| const $navItemParent = $navItem.parent() | |||
| const navItemIndex = $navItem.index() | |||
| $navItem.remove() | |||
| $(`${SELECTOR_TAB_PANE}.active`).remove() | |||
| if ($(SELECTOR_TAB_CONTENT).children().length == $(`${SELECTOR_TAB_EMPTY}, ${SELECTOR_TAB_LOADING}`).length) { | |||
| $(SELECTOR_TAB_EMPTY).show() | |||
| } else { | |||
| const prevNavItemIndex = navItemIndex - 1 | |||
| this.switchTab($navItemParent.children().eq(prevNavItemIndex).find('a.nav-link')) | |||
| } | |||
| } | |||
| } | |||
| const uniqueName = link.replace('./', '').replace(/["&'./:=?[\]]/gi, '-').replace(/(--)/gi, '') | |||
| const navId = `tab-${uniqueName}` | |||
| // Private | |||
| toggleFullscreen() { | |||
| if ($('body').hasClass(CLASS_NAME_FULLSCREEN_MODE)) { | |||
| $(`${SELECTOR_DATA_TOGGLE_FULLSCREEN} i`).removeClass(this._config.iconMinimize).addClass(this._config.iconMaximize) | |||
| $('body').removeClass(CLASS_NAME_FULLSCREEN_MODE) | |||
| $(`${SELECTOR_TAB_EMPTY}, ${SELECTOR_TAB_LOADING}`).height('auto') | |||
| $(SELECTOR_CONTENT_WRAPPER).height('auto') | |||
| $(SELECTOR_CONTENT_IFRAME).height('auto') | |||
| } else { | |||
| $(`${SELECTOR_DATA_TOGGLE_FULLSCREEN} i`).removeClass(this._config.iconMaximize).addClass(this._config.iconMinimize) | |||
| $('body').addClass(CLASS_NAME_FULLSCREEN_MODE) | |||
| } | |||
| $(window).trigger('resize') | |||
| this._fixHeight(true) | |||
| } | |||
| if (!this._config.allowDuplicates && $(`#${navId}`).length > 0) { | |||
| return this.switchTab(`#${navId}`) | |||
| _init() { | |||
| if (window.frameElement && this._config.autoIframeMode) { | |||
| $('body').addClass(CLASS_NAME_IFRAME_MODE) | |||
| } else if ($(SELECTOR_CONTENT_WRAPPER).hasClass(CLASS_NAME_IFRAME_MODE)) { | |||
| if ($(SELECTOR_TAB_CONTENT).children().length > 2) { | |||
| const $el = $(`${SELECTOR_TAB_PANE}:first-child`) | |||
| $el.show() | |||
| this._setItemActive($el.find('iframe').attr('src')) | |||
| } | |||
| this._setupListeners() | |||
| this._fixHeight(true) | |||
| } | |||
| } | |||
| if ((!this._config.allowDuplicates && $(`#${navId}`).length === 0) || this._config.allowDuplicates) { | |||
| this.createTab(title, link, uniqueName, autoOpen) | |||
| _navScroll(offset) { | |||
| const leftPos = $(SELECTOR_TAB_NAVBAR_NAV).scrollLeft() | |||
| $(SELECTOR_TAB_NAVBAR_NAV).animate({scrollLeft: (leftPos + offset)}, 250, 'linear') | |||
| } | |||
| } | |||
| switchTab(item) { | |||
| const $item = $(item) | |||
| const tabId = $item.attr('href') | |||
| _setupListeners() { | |||
| $(window).on('resize', () => { | |||
| setTimeout(() => { | |||
| this._fixHeight() | |||
| }, 1) | |||
| }) | |||
| $(document).on('click', `${SELECTOR_SIDEBAR_MENU_ITEM}, ${SELECTOR_SIDEBAR_SEARCH_ITEM}`, e => { | |||
| e.preventDefault() | |||
| this.openTabSidebar(e.target) | |||
| }) | |||
| $(SELECTOR_TAB_EMPTY).hide() | |||
| $(`${SELECTOR_TAB_NAVBAR_NAV} .active`).tab('dispose').removeClass('active') | |||
| this._fixHeight() | |||
| if (this._config.useNavbarItems) { | |||
| $(document).on('click', `${SELECTOR_HEADER_MENU_ITEM}, ${SELECTOR_HEADER_DROPDOWN_ITEM}`, e => { | |||
| e.preventDefault() | |||
| this.openTabSidebar(e.target) | |||
| }) | |||
| } | |||
| $(document).on('click', SELECTOR_TAB_NAVBAR_NAV_LINK, e => { | |||
| e.preventDefault() | |||
| this.onTabClick(e.target) | |||
| this.switchTab(e.target) | |||
| }) | |||
| $(document).on('click', SELECTOR_TAB_NAVBAR_NAV_LINK, e => { | |||
| e.preventDefault() | |||
| this.onTabClick(e.target) | |||
| this.switchTab(e.target) | |||
| }) | |||
| $(document).on('click', SELECTOR_DATA_TOGGLE_CLOSE, e => { | |||
| e.preventDefault() | |||
| let {target} = e | |||
| $item.tab('show') | |||
| $item.parents('li').addClass('active') | |||
| this.onTabChanged($item) | |||
| if (target.nodeName == 'I') { | |||
| target = e.target.offsetParent | |||
| } | |||
| if (this._config.autoItemActive) { | |||
| this._setItemActive($(`${tabId} iframe`).attr('src')) | |||
| } | |||
| } | |||
| removeActiveTab(type, element) { | |||
| if (type == 'all') { | |||
| $(SELECTOR_TAB_NAVBAR_NAV_ITEM).remove() | |||
| $(SELECTOR_TAB_PANE).remove() | |||
| $(SELECTOR_TAB_EMPTY).show() | |||
| } else if (type == 'all-other') { | |||
| $(`${SELECTOR_TAB_NAVBAR_NAV_ITEM}:not(.active)`).remove() | |||
| $(`${SELECTOR_TAB_PANE}:not(.active)`).remove() | |||
| } else if (type == 'only-this') { | |||
| const $navClose = $(element) | |||
| const $navItem = $navClose.parent('.nav-item') | |||
| const $navItemParent = $navItem.parent() | |||
| const navItemIndex = $navItem.index() | |||
| const tabId = $navClose.siblings('.nav-link').attr('aria-controls') | |||
| $navItem.remove() | |||
| $(`#${tabId}`).remove() | |||
| if ($(SELECTOR_TAB_CONTENT).children().length == $(`${SELECTOR_TAB_EMPTY}, ${SELECTOR_TAB_LOADING}`).length) { | |||
| $(SELECTOR_TAB_EMPTY).show() | |||
| } else { | |||
| const prevNavItemIndex = navItemIndex - 1 | |||
| this.switchTab($navItemParent.children().eq(prevNavItemIndex).find('a.nav-link')) | |||
| } | |||
| } else { | |||
| const $navItem = $(`${SELECTOR_TAB_NAVBAR_NAV_ITEM}.active`) | |||
| const $navItemParent = $navItem.parent() | |||
| const navItemIndex = $navItem.index() | |||
| $navItem.remove() | |||
| $(`${SELECTOR_TAB_PANE}.active`).remove() | |||
| if ($(SELECTOR_TAB_CONTENT).children().length == $(`${SELECTOR_TAB_EMPTY}, ${SELECTOR_TAB_LOADING}`).length) { | |||
| $(SELECTOR_TAB_EMPTY).show() | |||
| } else { | |||
| const prevNavItemIndex = navItemIndex - 1 | |||
| this.switchTab($navItemParent.children().eq(prevNavItemIndex).find('a.nav-link')) | |||
| } | |||
| } | |||
| } | |||
| toggleFullscreen() { | |||
| if ($('body').hasClass(CLASS_NAME_FULLSCREEN_MODE)) { | |||
| $(`${SELECTOR_DATA_TOGGLE_FULLSCREEN} i`).removeClass(this._config.iconMinimize).addClass(this._config.iconMaximize) | |||
| $('body').removeClass(CLASS_NAME_FULLSCREEN_MODE) | |||
| $(`${SELECTOR_TAB_EMPTY}, ${SELECTOR_TAB_LOADING}`).height('auto') | |||
| $(SELECTOR_CONTENT_WRAPPER).height('auto') | |||
| $(SELECTOR_CONTENT_IFRAME).height('auto') | |||
| } else { | |||
| $(`${SELECTOR_DATA_TOGGLE_FULLSCREEN} i`).removeClass(this._config.iconMaximize).addClass(this._config.iconMinimize) | |||
| $('body').addClass(CLASS_NAME_FULLSCREEN_MODE) | |||
| } | |||
| this.removeActiveTab(target.attributes['data-type'] ? target.attributes['data-type'].nodeValue : null, target) | |||
| }) | |||
| $(document).on('click', SELECTOR_DATA_TOGGLE_FULLSCREEN, e => { | |||
| e.preventDefault() | |||
| this.toggleFullscreen() | |||
| }) | |||
| let mousedown = false | |||
| let mousedownInterval = null | |||
| $(document).on('mousedown', SELECTOR_DATA_TOGGLE_SCROLL_LEFT, e => { | |||
| e.preventDefault() | |||
| clearInterval(mousedownInterval) | |||
| $(window).trigger('resize') | |||
| this._fixHeight(true) | |||
| } | |||
| let {scrollOffset} = this._config | |||
| // Private | |||
| if (!this._config.scrollBehaviorSwap) { | |||
| scrollOffset = -scrollOffset | |||
| } | |||
| _init() { | |||
| if (window.frameElement && this._config.autoIframeMode) { | |||
| $('body').addClass(CLASS_NAME_IFRAME_MODE) | |||
| } else if ($(SELECTOR_CONTENT_WRAPPER).hasClass(CLASS_NAME_IFRAME_MODE)) { | |||
| if ($(SELECTOR_TAB_CONTENT).children().length > 2) { | |||
| const $el = $(`${SELECTOR_TAB_PANE}:first-child`) | |||
| $el.show() | |||
| this._setItemActive($el.find('iframe').attr('src')) | |||
| } | |||
| mousedown = true | |||
| this._navScroll(scrollOffset) | |||
| this._setupListeners() | |||
| this._fixHeight(true) | |||
| } | |||
| } | |||
| mousedownInterval = setInterval(() => { | |||
| this._navScroll(scrollOffset) | |||
| }, 250) | |||
| }) | |||
| $(document).on('mousedown', SELECTOR_DATA_TOGGLE_SCROLL_RIGHT, e => { | |||
| e.preventDefault() | |||
| clearInterval(mousedownInterval) | |||
| _navScroll(offset) { | |||
| const leftPos = $(SELECTOR_TAB_NAVBAR_NAV).scrollLeft() | |||
| $(SELECTOR_TAB_NAVBAR_NAV).animate({ scrollLeft: (leftPos + offset) }, 250, 'linear') | |||
| } | |||
| let {scrollOffset} = this._config | |||
| _setupListeners() { | |||
| $(window).on('resize', () => { | |||
| setTimeout(() => { | |||
| this._fixHeight() | |||
| }, 1) | |||
| }) | |||
| $(document).on('click', `${SELECTOR_SIDEBAR_MENU_ITEM}, ${SELECTOR_SIDEBAR_SEARCH_ITEM}`, e => { | |||
| e.preventDefault() | |||
| this.openTabSidebar(e.target) | |||
| }) | |||
| if (this._config.useNavbarItems) { | |||
| $(document).on('click', `${SELECTOR_HEADER_MENU_ITEM}, ${SELECTOR_HEADER_DROPDOWN_ITEM}`, e => { | |||
| e.preventDefault() | |||
| this.openTabSidebar(e.target) | |||
| }) | |||
| } | |||
| if (this._config.scrollBehaviorSwap) { | |||
| scrollOffset = -scrollOffset | |||
| } | |||
| mousedown = true | |||
| this._navScroll(scrollOffset) | |||
| $(document).on('click', SELECTOR_TAB_NAVBAR_NAV_LINK, e => { | |||
| e.preventDefault() | |||
| this.onTabClick(e.target) | |||
| this.switchTab(e.target) | |||
| }) | |||
| $(document).on('click', SELECTOR_TAB_NAVBAR_NAV_LINK, e => { | |||
| e.preventDefault() | |||
| this.onTabClick(e.target) | |||
| this.switchTab(e.target) | |||
| }) | |||
| $(document).on('click', SELECTOR_DATA_TOGGLE_CLOSE, e => { | |||
| e.preventDefault() | |||
| let { target } = e | |||
| if (target.nodeName == 'I') { | |||
| target = e.target.offsetParent | |||
| } | |||
| this.removeActiveTab(target.attributes['data-type'] ? target.attributes['data-type'].nodeValue : null, target) | |||
| }) | |||
| $(document).on('click', SELECTOR_DATA_TOGGLE_FULLSCREEN, e => { | |||
| e.preventDefault() | |||
| this.toggleFullscreen() | |||
| }) | |||
| let mousedown = false | |||
| let mousedownInterval = null | |||
| $(document).on('mousedown', SELECTOR_DATA_TOGGLE_SCROLL_LEFT, e => { | |||
| e.preventDefault() | |||
| clearInterval(mousedownInterval) | |||
| let { scrollOffset } = this._config | |||
| if (!this._config.scrollBehaviorSwap) { | |||
| scrollOffset = -scrollOffset | |||
| } | |||
| mousedown = true | |||
| this._navScroll(scrollOffset) | |||
| mousedownInterval = setInterval(() => { | |||
| this._navScroll(scrollOffset) | |||
| }, 250) | |||
| }) | |||
| $(document).on('mousedown', SELECTOR_DATA_TOGGLE_SCROLL_RIGHT, e => { | |||
| e.preventDefault() | |||
| clearInterval(mousedownInterval) | |||
| let { scrollOffset } = this._config | |||
| if (this._config.scrollBehaviorSwap) { | |||
| scrollOffset = -scrollOffset | |||
| } | |||
| mousedown = true | |||
| this._navScroll(scrollOffset) | |||
| mousedownInterval = setInterval(() => { | |||
| this._navScroll(scrollOffset) | |||
| }, 250) | |||
| }) | |||
| $(document).on('mouseup', () => { | |||
| if (mousedown) { | |||
| mousedown = false | |||
| clearInterval(mousedownInterval) | |||
| mousedownInterval = null | |||
| } | |||
| }) | |||
| } | |||
| _setItemActive(href) { | |||
| $(`${SELECTOR_SIDEBAR_MENU_ITEM}, ${SELECTOR_HEADER_DROPDOWN_ITEM}`).removeClass('active') | |||
| $(SELECTOR_HEADER_MENU_ITEM).parent().removeClass('active') | |||
| const $headerMenuItem = $(`${SELECTOR_HEADER_MENU_ITEM}[href$="${href}"]`) | |||
| const $headerDropdownItem = $(`${SELECTOR_HEADER_DROPDOWN_ITEM}[href$="${href}"]`) | |||
| const $sidebarMenuItem = $(`${SELECTOR_SIDEBAR_MENU_ITEM}[href$="${href}"]`) | |||
| $headerMenuItem.each((i, e) => { | |||
| $(e).parent().addClass('active') | |||
| }) | |||
| $headerDropdownItem.each((i, e) => { | |||
| $(e).addClass('active') | |||
| }) | |||
| $sidebarMenuItem.each((i, e) => { | |||
| $(e).addClass('active') | |||
| $(e).parents('.nav-treeview').prevAll('.nav-link').addClass('active') | |||
| }) | |||
| } | |||
| _fixHeight(tabEmpty = false) { | |||
| if ($('body').hasClass(CLASS_NAME_FULLSCREEN_MODE)) { | |||
| const windowHeight = $(window).height() | |||
| const navbarHeight = $(SELECTOR_TAB_NAV).outerHeight() | |||
| $(`${SELECTOR_TAB_EMPTY}, ${SELECTOR_TAB_LOADING}, ${SELECTOR_CONTENT_IFRAME}`).height(windowHeight - navbarHeight) | |||
| $(SELECTOR_CONTENT_WRAPPER).height(windowHeight) | |||
| } else { | |||
| const contentWrapperHeight = parseFloat($(SELECTOR_CONTENT_WRAPPER).css('height')) | |||
| const navbarHeight = $(SELECTOR_TAB_NAV).outerHeight() | |||
| if (tabEmpty == true) { | |||
| setTimeout(() => { | |||
| $(`${SELECTOR_TAB_EMPTY}, ${SELECTOR_TAB_LOADING}`).height(contentWrapperHeight - navbarHeight) | |||
| }, 50) | |||
| } else { | |||
| $(SELECTOR_CONTENT_IFRAME).height(contentWrapperHeight - navbarHeight) | |||
| } | |||
| mousedownInterval = setInterval(() => { | |||
| this._navScroll(scrollOffset) | |||
| }, 250) | |||
| }) | |||
| $(document).on('mouseup', () => { | |||
| if (mousedown) { | |||
| mousedown = false | |||
| clearInterval(mousedownInterval) | |||
| mousedownInterval = null | |||
| } | |||
| }) | |||
| } | |||
| } | |||
| // Static | |||
| _setItemActive(href) { | |||
| $(`${SELECTOR_SIDEBAR_MENU_ITEM}, ${SELECTOR_HEADER_DROPDOWN_ITEM}`).removeClass('active') | |||
| $(SELECTOR_HEADER_MENU_ITEM).parent().removeClass('active') | |||
| static _jQueryInterface(operation, ...args) { | |||
| let data = $(this).data(DATA_KEY) | |||
| const _options = $.extend({}, Default, $(this).data()) | |||
| const $headerMenuItem = $(`${SELECTOR_HEADER_MENU_ITEM}[href$="${href}"]`) | |||
| const $headerDropdownItem = $(`${SELECTOR_HEADER_DROPDOWN_ITEM}[href$="${href}"]`) | |||
| const $sidebarMenuItem = $(`${SELECTOR_SIDEBAR_MENU_ITEM}[href$="${href}"]`) | |||
| if (!data) { | |||
| data = new IFrame(this, _options) | |||
| $(this).data(DATA_KEY, data) | |||
| $headerMenuItem.each((i, e) => { | |||
| $(e).parent().addClass('active') | |||
| }) | |||
| $headerDropdownItem.each((i, e) => { | |||
| $(e).addClass('active') | |||
| }) | |||
| $sidebarMenuItem.each((i, e) => { | |||
| $(e).addClass('active') | |||
| $(e).parents('.nav-treeview').prevAll('.nav-link').addClass('active') | |||
| }) | |||
| } | |||
| if (typeof operation === 'string' && /createTab|openTabSidebar|switchTab|removeActiveTab/.test(operation)) { | |||
| data[operation](...args) | |||
| // Static | |||
| _fixHeight(tabEmpty = false) { | |||
| if ($('body').hasClass(CLASS_NAME_FULLSCREEN_MODE)) { | |||
| const windowHeight = $(window).height() | |||
| const navbarHeight = $(SELECTOR_TAB_NAV).outerHeight() | |||
| $(`${SELECTOR_TAB_EMPTY}, ${SELECTOR_TAB_LOADING}, ${SELECTOR_CONTENT_IFRAME}`).height(windowHeight - navbarHeight) | |||
| $(SELECTOR_CONTENT_WRAPPER).height(windowHeight) | |||
| } else { | |||
| const contentWrapperHeight = parseFloat($(SELECTOR_CONTENT_WRAPPER).css('height')) | |||
| const navbarHeight = $(SELECTOR_TAB_NAV).outerHeight() | |||
| if (tabEmpty == true) { | |||
| setTimeout(() => { | |||
| $(`${SELECTOR_TAB_EMPTY}, ${SELECTOR_TAB_LOADING}`).height(contentWrapperHeight - navbarHeight) | |||
| }, 50) | |||
| } else { | |||
| $(SELECTOR_CONTENT_IFRAME).height(contentWrapperHeight - navbarHeight) | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| @@ -395,7 +395,7 @@ class IFrame { | |||
| */ | |||
| $(window).on('load', () => { | |||
| IFrame._jQueryInterface.call($(SELECTOR_DATA_TOGGLE)) | |||
| IFrame._jQueryInterface.call($(SELECTOR_DATA_TOGGLE)) | |||
| }) | |||
| /** | |||
| @@ -406,8 +406,8 @@ $(window).on('load', () => { | |||
| $.fn[NAME] = IFrame._jQueryInterface | |||
| $.fn[NAME].Constructor = IFrame | |||
| $.fn[NAME].noConflict = function () { | |||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||
| return IFrame._jQueryInterface | |||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||
| return IFrame._jQueryInterface | |||
| } | |||
| export default IFrame | |||
| @@ -35,12 +35,12 @@ const CLASS_NAME_CONTROL_SIDEBAR_SLIDE_OPEN = 'control-sidebar-slide-open' | |||
| const CLASS_NAME_CONTROL_SIDEBAR_OPEN = 'control-sidebar-open' | |||
| const Default = { | |||
| scrollbarTheme: 'os-theme-light', | |||
| scrollbarAutoHide: 'l', | |||
| panelAutoHeight: true, | |||
| panelAutoHeightMode: 'min-height', | |||
| preloadDuration: 200, | |||
| loginRegisterAutoHeight: true | |||
| scrollbarTheme: 'os-theme-light', | |||
| scrollbarAutoHide: 'l', | |||
| panelAutoHeight: true, | |||
| panelAutoHeightMode: 'min-height', | |||
| preloadDuration: 200, | |||
| loginRegisterAutoHeight: true | |||
| } | |||
| /** | |||
| @@ -49,180 +49,180 @@ const Default = { | |||
| */ | |||
| class Layout { | |||
| constructor(element, config) { | |||
| this._config = config | |||
| this._element = element | |||
| } | |||
| constructor(element, config) { | |||
| this._config = config | |||
| this._element = element | |||
| } | |||
| // Public | |||
| // Public | |||
| fixLayoutHeight(extra = null) { | |||
| const $body = $('body') | |||
| let controlSidebar = 0 | |||
| static _jQueryInterface(config = '') { | |||
| return this.each(function () { | |||
| let data = $(this).data(DATA_KEY) | |||
| const _options = $.extend({}, Default, $(this).data()) | |||
| if ($body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_SLIDE_OPEN) || $body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_OPEN) || extra === 'control_sidebar') { | |||
| controlSidebar = $(SELECTOR_CONTROL_SIDEBAR_CONTENT).outerHeight() | |||
| } | |||
| if (!data) { | |||
| data = new Layout($(this), _options) | |||
| $(this).data(DATA_KEY, data) | |||
| } | |||
| const heights = { | |||
| window: $(window).height(), | |||
| header: $(SELECTOR_HEADER).length > 0 ? $(SELECTOR_HEADER).outerHeight() : 0, | |||
| footer: $(SELECTOR_FOOTER).length > 0 ? $(SELECTOR_FOOTER).outerHeight() : 0, | |||
| sidebar: $(SELECTOR_SIDEBAR).length > 0 ? $(SELECTOR_SIDEBAR).height() : 0, | |||
| controlSidebar | |||
| if (config === 'init' || config === '') { | |||
| data._init() | |||
| } else if (config === 'fixLayoutHeight' || config === 'fixLoginRegisterHeight') { | |||
| data[config]() | |||
| } | |||
| }) | |||
| } | |||
| const max = this._max(heights) | |||
| let offset = this._config.panelAutoHeight | |||
| fixLayoutHeight(extra = null) { | |||
| const $body = $('body') | |||
| let controlSidebar = 0 | |||
| if (offset === true) { | |||
| offset = 0 | |||
| } | |||
| if ($body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_SLIDE_OPEN) || $body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_OPEN) || extra === 'control_sidebar') { | |||
| controlSidebar = $(SELECTOR_CONTROL_SIDEBAR_CONTENT).outerHeight() | |||
| } | |||
| const $contentSelector = $(SELECTOR_CONTENT) | |||
| const heights = { | |||
| window: $(window).height(), | |||
| header: $(SELECTOR_HEADER).length > 0 ? $(SELECTOR_HEADER).outerHeight() : 0, | |||
| footer: $(SELECTOR_FOOTER).length > 0 ? $(SELECTOR_FOOTER).outerHeight() : 0, | |||
| sidebar: $(SELECTOR_SIDEBAR).length > 0 ? $(SELECTOR_SIDEBAR).height() : 0, | |||
| controlSidebar | |||
| } | |||
| if (offset !== false) { | |||
| if (max === heights.controlSidebar) { | |||
| $contentSelector.css(this._config.panelAutoHeightMode, (max + offset)) | |||
| } else if (max === heights.window) { | |||
| $contentSelector.css(this._config.panelAutoHeightMode, (max + offset) - heights.header - heights.footer) | |||
| } else { | |||
| $contentSelector.css(this._config.panelAutoHeightMode, (max + offset) - heights.header) | |||
| } | |||
| const max = this._max(heights) | |||
| let offset = this._config.panelAutoHeight | |||
| if (this._isFooterFixed()) { | |||
| $contentSelector.css(this._config.panelAutoHeightMode, parseFloat($contentSelector.css(this._config.panelAutoHeightMode)) + heights.footer) | |||
| } | |||
| } | |||
| if (offset === true) { | |||
| offset = 0 | |||
| } | |||
| if (!$body.hasClass(CLASS_NAME_LAYOUT_FIXED)) { | |||
| return | |||
| } | |||
| const $contentSelector = $(SELECTOR_CONTENT) | |||
| if (typeof $.fn.overlayScrollbars !== 'undefined') { | |||
| $(SELECTOR_SIDEBAR).overlayScrollbars({ | |||
| className: this._config.scrollbarTheme, | |||
| sizeAutoCapable: true, | |||
| scrollbars: { | |||
| autoHide: this._config.scrollbarAutoHide, | |||
| clickScrolling: true | |||
| } | |||
| }) | |||
| } else { | |||
| $(SELECTOR_SIDEBAR).css('overflow-y', 'auto') | |||
| } | |||
| } | |||
| if (offset !== false) { | |||
| if (max === heights.controlSidebar) { | |||
| $contentSelector.css(this._config.panelAutoHeightMode, (max + offset)) | |||
| } else if (max === heights.window) { | |||
| $contentSelector.css(this._config.panelAutoHeightMode, (max + offset) - heights.header - heights.footer) | |||
| } else { | |||
| $contentSelector.css(this._config.panelAutoHeightMode, (max + offset) - heights.header) | |||
| } | |||
| fixLoginRegisterHeight() { | |||
| const $body = $('body') | |||
| const $selector = $(`${SELECTOR_LOGIN_BOX}, ${SELECTOR_REGISTER_BOX}`) | |||
| if (this._isFooterFixed()) { | |||
| $contentSelector.css(this._config.panelAutoHeightMode, parseFloat($contentSelector.css(this._config.panelAutoHeightMode)) + heights.footer) | |||
| } | |||
| } | |||
| if ($selector.length === 0) { | |||
| $body.css('height', 'auto') | |||
| $('html').css('height', 'auto') | |||
| } else { | |||
| const boxHeight = $selector.height() | |||
| if (!$body.hasClass(CLASS_NAME_LAYOUT_FIXED)) { | |||
| return | |||
| } | |||
| if ($body.css(this._config.panelAutoHeightMode) !== boxHeight) { | |||
| $body.css(this._config.panelAutoHeightMode, boxHeight) | |||
| } | |||
| if (typeof $.fn.overlayScrollbars !== 'undefined') { | |||
| $(SELECTOR_SIDEBAR).overlayScrollbars({ | |||
| className: this._config.scrollbarTheme, | |||
| sizeAutoCapable: true, | |||
| scrollbars: { | |||
| autoHide: this._config.scrollbarAutoHide, | |||
| clickScrolling: true | |||
| } | |||
| }) | |||
| } else { | |||
| $(SELECTOR_SIDEBAR).css('overflow-y', 'auto') | |||
| } | |||
| } | |||
| } | |||
| // Private | |||
| // Private | |||
| _init() { | |||
| // Activate layout height watcher | |||
| this.fixLayoutHeight() | |||
| fixLoginRegisterHeight() { | |||
| const $body = $('body') | |||
| const $selector = $(`${SELECTOR_LOGIN_BOX}, ${SELECTOR_REGISTER_BOX}`) | |||
| if (this._config.loginRegisterAutoHeight === true) { | |||
| this.fixLoginRegisterHeight() | |||
| } else if (this._config.loginRegisterAutoHeight === parseInt(this._config.loginRegisterAutoHeight, 10)) { | |||
| setInterval(this.fixLoginRegisterHeight, this._config.loginRegisterAutoHeight) | |||
| } | |||
| if ($selector.length === 0) { | |||
| $body.css('height', 'auto') | |||
| $('html').css('height', 'auto') | |||
| } else { | |||
| const boxHeight = $selector.height() | |||
| $(SELECTOR_SIDEBAR) | |||
| .on('collapsed.lte.treeview expanded.lte.treeview', () => { | |||
| this.fixLayoutHeight() | |||
| }) | |||
| $(SELECTOR_MAIN_SIDEBAR) | |||
| .on('mouseenter mouseleave', () => { | |||
| if ($('body').hasClass(CLASS_NAME_SIDEBAR_COLLAPSED)) { | |||
| this.fixLayoutHeight() | |||
| if ($body.css(this._config.panelAutoHeightMode) !== boxHeight) { | |||
| $body.css(this._config.panelAutoHeightMode, boxHeight) | |||
| } | |||
| } | |||
| }) | |||
| $(SELECTOR_PUSHMENU_BTN) | |||
| .on('collapsed.lte.pushmenu shown.lte.pushmenu', () => { | |||
| setTimeout(() => { | |||
| this.fixLayoutHeight() | |||
| }, 300) | |||
| }) | |||
| } | |||
| $(SELECTOR_CONTROL_SIDEBAR_BTN) | |||
| .on('collapsed.lte.controlsidebar', () => { | |||
| _init() { | |||
| // Activate layout height watcher | |||
| this.fixLayoutHeight() | |||
| }) | |||
| .on('expanded.lte.controlsidebar', () => { | |||
| this.fixLayoutHeight('control_sidebar') | |||
| }) | |||
| $(window).resize(() => { | |||
| this.fixLayoutHeight() | |||
| }) | |||
| if (this._config.loginRegisterAutoHeight === true) { | |||
| this.fixLoginRegisterHeight() | |||
| } else if (this._config.loginRegisterAutoHeight === parseInt(this._config.loginRegisterAutoHeight, 10)) { | |||
| setInterval(this.fixLoginRegisterHeight, this._config.loginRegisterAutoHeight) | |||
| } | |||
| setTimeout(() => { | |||
| $('body.hold-transition').removeClass('hold-transition') | |||
| }, 50) | |||
| $(SELECTOR_SIDEBAR) | |||
| .on('collapsed.lte.treeview expanded.lte.treeview', () => { | |||
| this.fixLayoutHeight() | |||
| }) | |||
| $(SELECTOR_MAIN_SIDEBAR) | |||
| .on('mouseenter mouseleave', () => { | |||
| if ($('body').hasClass(CLASS_NAME_SIDEBAR_COLLAPSED)) { | |||
| this.fixLayoutHeight() | |||
| } | |||
| }) | |||
| $(SELECTOR_PUSHMENU_BTN) | |||
| .on('collapsed.lte.pushmenu shown.lte.pushmenu', () => { | |||
| setTimeout(() => { | |||
| this.fixLayoutHeight() | |||
| }, 300) | |||
| }) | |||
| $(SELECTOR_CONTROL_SIDEBAR_BTN) | |||
| .on('collapsed.lte.controlsidebar', () => { | |||
| this.fixLayoutHeight() | |||
| }) | |||
| .on('expanded.lte.controlsidebar', () => { | |||
| this.fixLayoutHeight('control_sidebar') | |||
| }) | |||
| $(window).resize(() => { | |||
| this.fixLayoutHeight() | |||
| }) | |||
| setTimeout(() => { | |||
| const $preloader = $(SELECTOR_PRELOADER) | |||
| if ($preloader) { | |||
| $preloader.css('height', 0) | |||
| setTimeout(() => { | |||
| $preloader.children().hide() | |||
| }, 200) | |||
| } | |||
| }, this._config.preloadDuration) | |||
| } | |||
| _max(numbers) { | |||
| // Calculate the maximum number in a list | |||
| let max = 0 | |||
| Object.keys(numbers).forEach(key => { | |||
| if (numbers[key] > max) { | |||
| max = numbers[key] | |||
| } | |||
| }) | |||
| $('body.hold-transition').removeClass('hold-transition') | |||
| }, 50) | |||
| return max | |||
| } | |||
| setTimeout(() => { | |||
| const $preloader = $(SELECTOR_PRELOADER) | |||
| if ($preloader) { | |||
| $preloader.css('height', 0) | |||
| setTimeout(() => { | |||
| $preloader.children().hide() | |||
| }, 200) | |||
| } | |||
| }, this._config.preloadDuration) | |||
| } | |||
| _isFooterFixed() { | |||
| return $(SELECTOR_FOOTER).css('position') === 'fixed' | |||
| } | |||
| _max(numbers) { | |||
| // Calculate the maximum number in a list | |||
| let max = 0 | |||
| // Static | |||
| Object.keys(numbers).forEach(key => { | |||
| if (numbers[key] > max) { | |||
| max = numbers[key] | |||
| } | |||
| }) | |||
| static _jQueryInterface(config = '') { | |||
| return this.each(function () { | |||
| let data = $(this).data(DATA_KEY) | |||
| const _options = $.extend({}, Default, $(this).data()) | |||
| return max | |||
| } | |||
| if (!data) { | |||
| data = new Layout($(this), _options) | |||
| $(this).data(DATA_KEY, data) | |||
| } | |||
| // Static | |||
| if (config === 'init' || config === '') { | |||
| data._init() | |||
| } else if (config === 'fixLayoutHeight' || config === 'fixLoginRegisterHeight') { | |||
| data[config]() | |||
| } | |||
| }) | |||
| } | |||
| _isFooterFixed() { | |||
| return $(SELECTOR_FOOTER).css('position') === 'fixed' | |||
| } | |||
| } | |||
| /** | |||
| @@ -231,16 +231,16 @@ class Layout { | |||
| */ | |||
| $(window).on('load', () => { | |||
| Layout._jQueryInterface.call($('body')) | |||
| Layout._jQueryInterface.call($('body')) | |||
| }) | |||
| $(`${SELECTOR_SIDEBAR} a`) | |||
| .on('focusin', () => { | |||
| $(SELECTOR_MAIN_SIDEBAR).addClass(CLASS_NAME_SIDEBAR_FOCUSED) | |||
| }) | |||
| .on('focusout', () => { | |||
| $(SELECTOR_MAIN_SIDEBAR).removeClass(CLASS_NAME_SIDEBAR_FOCUSED) | |||
| }) | |||
| .on('focusin', () => { | |||
| $(SELECTOR_MAIN_SIDEBAR).addClass(CLASS_NAME_SIDEBAR_FOCUSED) | |||
| }) | |||
| .on('focusout', () => { | |||
| $(SELECTOR_MAIN_SIDEBAR).removeClass(CLASS_NAME_SIDEBAR_FOCUSED) | |||
| }) | |||
| /** | |||
| * jQuery API | |||
| @@ -250,8 +250,8 @@ $(`${SELECTOR_SIDEBAR} a`) | |||
| $.fn[NAME] = Layout._jQueryInterface | |||
| $.fn[NAME].Constructor = Layout | |||
| $.fn[NAME].noConflict = function () { | |||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||
| return Layout._jQueryInterface | |||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||
| return Layout._jQueryInterface | |||
| } | |||
| export default Layout | |||
| @@ -23,8 +23,8 @@ const SELECTOR_SEARCH_INPUT = '.form-control' | |||
| const CLASS_NAME_OPEN = 'navbar-search-open' | |||
| const Default = { | |||
| resetOnClose: true, | |||
| target: SELECTOR_SEARCH_BLOCK | |||
| resetOnClose: true, | |||
| target: SELECTOR_SEARCH_BLOCK | |||
| } | |||
| /** | |||
| @@ -33,53 +33,53 @@ const Default = { | |||
| */ | |||
| class NavbarSearch { | |||
| constructor(_element, _options) { | |||
| this._element = _element | |||
| this._config = $.extend({}, Default, _options) | |||
| } | |||
| constructor(_element, _options) { | |||
| this._element = _element | |||
| this._config = $.extend({}, Default, _options) | |||
| } | |||
| // Public | |||
| // Public | |||
| open() { | |||
| $(this._config.target).css('display', 'flex').hide().fadeIn().addClass(CLASS_NAME_OPEN) | |||
| $(`${this._config.target} ${SELECTOR_SEARCH_INPUT}`).focus() | |||
| } | |||
| static _jQueryInterface(options) { | |||
| return this.each(function () { | |||
| let data = $(this).data(DATA_KEY) | |||
| const _options = $.extend({}, Default, $(this).data()) | |||
| close() { | |||
| $(this._config.target).fadeOut().removeClass(CLASS_NAME_OPEN) | |||
| if (!data) { | |||
| data = new NavbarSearch(this, _options) | |||
| $(this).data(DATA_KEY, data) | |||
| } | |||
| if (this._config.resetOnClose) { | |||
| $(`${this._config.target} ${SELECTOR_SEARCH_INPUT}`).val('') | |||
| } | |||
| } | |||
| if (!/toggle|close|open/.test(options)) { | |||
| throw new Error(`Undefined method ${options}`) | |||
| } | |||
| toggle() { | |||
| if ($(this._config.target).hasClass(CLASS_NAME_OPEN)) { | |||
| this.close() | |||
| } else { | |||
| this.open() | |||
| data[options]() | |||
| }) | |||
| } | |||
| } | |||
| // Static | |||
| open() { | |||
| $(this._config.target).css('display', 'flex').hide().fadeIn().addClass(CLASS_NAME_OPEN) | |||
| $(`${this._config.target} ${SELECTOR_SEARCH_INPUT}`).focus() | |||
| } | |||
| static _jQueryInterface(options) { | |||
| return this.each(function () { | |||
| let data = $(this).data(DATA_KEY) | |||
| const _options = $.extend({}, Default, $(this).data()) | |||
| close() { | |||
| $(this._config.target).fadeOut().removeClass(CLASS_NAME_OPEN) | |||
| if (!data) { | |||
| data = new NavbarSearch(this, _options) | |||
| $(this).data(DATA_KEY, data) | |||
| } | |||
| if (this._config.resetOnClose) { | |||
| $(`${this._config.target} ${SELECTOR_SEARCH_INPUT}`).val('') | |||
| } | |||
| } | |||
| if (!/toggle|close|open/.test(options)) { | |||
| throw new Error(`Undefined method ${options}`) | |||
| } | |||
| // Static | |||
| data[options]() | |||
| }) | |||
| } | |||
| toggle() { | |||
| if ($(this._config.target).hasClass(CLASS_NAME_OPEN)) { | |||
| this.close() | |||
| } else { | |||
| this.open() | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| @@ -87,15 +87,15 @@ class NavbarSearch { | |||
| * ==================================================== | |||
| */ | |||
| $(document).on('click', SELECTOR_TOGGLE_BUTTON, event => { | |||
| event.preventDefault() | |||
| event.preventDefault() | |||
| let button = $(event.currentTarget) | |||
| let button = $(event.currentTarget) | |||
| if (button.data('widget') !== 'navbar-search') { | |||
| button = button.closest(SELECTOR_TOGGLE_BUTTON) | |||
| } | |||
| if (button.data('widget') !== 'navbar-search') { | |||
| button = button.closest(SELECTOR_TOGGLE_BUTTON) | |||
| } | |||
| NavbarSearch._jQueryInterface.call(button, 'toggle') | |||
| NavbarSearch._jQueryInterface.call(button, 'toggle') | |||
| }) | |||
| /** | |||
| @@ -106,8 +106,8 @@ $(document).on('click', SELECTOR_TOGGLE_BUTTON, event => { | |||
| $.fn[NAME] = NavbarSearch._jQueryInterface | |||
| $.fn[NAME].Constructor = NavbarSearch | |||
| $.fn[NAME].noConflict = function () { | |||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||
| return NavbarSearch._jQueryInterface | |||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||
| return NavbarSearch._jQueryInterface | |||
| } | |||
| export default NavbarSearch | |||
| @@ -31,9 +31,9 @@ const CLASS_NAME_IS_OPENING = 'sidebar-is-opening' | |||
| const CLASS_NAME_CLOSED = 'sidebar-closed' | |||
| const Default = { | |||
| autoCollapseSize: 992, | |||
| enableRemember: false, | |||
| noTransitionAfterReload: true | |||
| autoCollapseSize: 992, | |||
| enableRemember: false, | |||
| noTransitionAfterReload: true | |||
| } | |||
| /** | |||
| @@ -42,149 +42,149 @@ const Default = { | |||
| */ | |||
| class PushMenu { | |||
| constructor(element, options) { | |||
| this._element = element | |||
| this._options = $.extend({}, Default, options) | |||
| constructor(element, options) { | |||
| this._element = element | |||
| this._options = $.extend({}, Default, options) | |||
| if ($(SELECTOR_OVERLAY).length === 0) { | |||
| this._addOverlay() | |||
| if ($(SELECTOR_OVERLAY).length === 0) { | |||
| this._addOverlay() | |||
| } | |||
| this._init() | |||
| } | |||
| this._init() | |||
| } | |||
| // Public | |||
| // Public | |||
| static _jQueryInterface(operation) { | |||
| return this.each(function () { | |||
| let data = $(this).data(DATA_KEY) | |||
| const _options = $.extend({}, Default, $(this).data()) | |||
| expand() { | |||
| const $bodySelector = $(SELECTOR_BODY) | |||
| if (!data) { | |||
| data = new PushMenu(this, _options) | |||
| $(this).data(DATA_KEY, data) | |||
| } | |||
| if (this._options.autoCollapseSize && $(window).width() <= this._options.autoCollapseSize) { | |||
| $bodySelector.addClass(CLASS_NAME_OPEN) | |||
| if (typeof operation === 'string' && /collapse|expand|toggle/.test(operation)) { | |||
| data[operation]() | |||
| } | |||
| }) | |||
| } | |||
| $bodySelector.addClass(CLASS_NAME_IS_OPENING).removeClass(`${CLASS_NAME_COLLAPSED} ${CLASS_NAME_CLOSED}`).delay(50).queue(function () { | |||
| $bodySelector.removeClass(CLASS_NAME_IS_OPENING) | |||
| $(this).dequeue() | |||
| }) | |||
| expand() { | |||
| const $bodySelector = $(SELECTOR_BODY) | |||
| if (this._options.enableRemember) { | |||
| localStorage.setItem(`remember${EVENT_KEY}`, CLASS_NAME_OPEN) | |||
| } | |||
| if (this._options.autoCollapseSize && $(window).width() <= this._options.autoCollapseSize) { | |||
| $bodySelector.addClass(CLASS_NAME_OPEN) | |||
| } | |||
| $(this._element).trigger($.Event(EVENT_SHOWN)) | |||
| } | |||
| $bodySelector.addClass(CLASS_NAME_IS_OPENING).removeClass(`${CLASS_NAME_COLLAPSED} ${CLASS_NAME_CLOSED}`).delay(50).queue(function () { | |||
| $bodySelector.removeClass(CLASS_NAME_IS_OPENING) | |||
| $(this).dequeue() | |||
| }) | |||
| collapse() { | |||
| const $bodySelector = $(SELECTOR_BODY) | |||
| if (this._options.enableRemember) { | |||
| localStorage.setItem(`remember${EVENT_KEY}`, CLASS_NAME_OPEN) | |||
| } | |||
| if (this._options.autoCollapseSize && $(window).width() <= this._options.autoCollapseSize) { | |||
| $bodySelector.removeClass(CLASS_NAME_OPEN).addClass(CLASS_NAME_CLOSED) | |||
| $(this._element).trigger($.Event(EVENT_SHOWN)) | |||
| } | |||
| $bodySelector.addClass(CLASS_NAME_COLLAPSED) | |||
| collapse() { | |||
| const $bodySelector = $(SELECTOR_BODY) | |||
| if (this._options.enableRemember) { | |||
| localStorage.setItem(`remember${EVENT_KEY}`, CLASS_NAME_COLLAPSED) | |||
| } | |||
| if (this._options.autoCollapseSize && $(window).width() <= this._options.autoCollapseSize) { | |||
| $bodySelector.removeClass(CLASS_NAME_OPEN).addClass(CLASS_NAME_CLOSED) | |||
| } | |||
| $bodySelector.addClass(CLASS_NAME_COLLAPSED) | |||
| $(this._element).trigger($.Event(EVENT_COLLAPSED)) | |||
| } | |||
| if (this._options.enableRemember) { | |||
| localStorage.setItem(`remember${EVENT_KEY}`, CLASS_NAME_COLLAPSED) | |||
| } | |||
| toggle() { | |||
| if ($(SELECTOR_BODY).hasClass(CLASS_NAME_COLLAPSED)) { | |||
| this.expand() | |||
| } else { | |||
| this.collapse() | |||
| $(this._element).trigger($.Event(EVENT_COLLAPSED)) | |||
| } | |||
| } | |||
| autoCollapse(resize = false) { | |||
| if (!this._options.autoCollapseSize) { | |||
| return | |||
| toggle() { | |||
| if ($(SELECTOR_BODY).hasClass(CLASS_NAME_COLLAPSED)) { | |||
| this.expand() | |||
| } else { | |||
| this.collapse() | |||
| } | |||
| } | |||
| const $bodySelector = $(SELECTOR_BODY) | |||
| if ($(window).width() <= this._options.autoCollapseSize) { | |||
| if (!$bodySelector.hasClass(CLASS_NAME_OPEN)) { | |||
| this.collapse() | |||
| } | |||
| } else if (resize === true) { | |||
| if ($bodySelector.hasClass(CLASS_NAME_OPEN)) { | |||
| $bodySelector.removeClass(CLASS_NAME_OPEN) | |||
| } else if ($bodySelector.hasClass(CLASS_NAME_CLOSED)) { | |||
| this.expand() | |||
| } | |||
| autoCollapse(resize = false) { | |||
| if (!this._options.autoCollapseSize) { | |||
| return | |||
| } | |||
| const $bodySelector = $(SELECTOR_BODY) | |||
| if ($(window).width() <= this._options.autoCollapseSize) { | |||
| if (!$bodySelector.hasClass(CLASS_NAME_OPEN)) { | |||
| this.collapse() | |||
| } | |||
| } else if (resize === true) { | |||
| if ($bodySelector.hasClass(CLASS_NAME_OPEN)) { | |||
| $bodySelector.removeClass(CLASS_NAME_OPEN) | |||
| } else if ($bodySelector.hasClass(CLASS_NAME_CLOSED)) { | |||
| this.expand() | |||
| } | |||
| } | |||
| } | |||
| } | |||
| remember() { | |||
| if (!this._options.enableRemember) { | |||
| return | |||
| // Private | |||
| remember() { | |||
| if (!this._options.enableRemember) { | |||
| return | |||
| } | |||
| const $body = $('body') | |||
| const toggleState = localStorage.getItem(`remember${EVENT_KEY}`) | |||
| if (toggleState === CLASS_NAME_COLLAPSED) { | |||
| if (this._options.noTransitionAfterReload) { | |||
| $body.addClass('hold-transition').addClass(CLASS_NAME_COLLAPSED).delay(50).queue(function () { | |||
| $(this).removeClass('hold-transition') | |||
| $(this).dequeue() | |||
| }) | |||
| } else { | |||
| $body.addClass(CLASS_NAME_COLLAPSED) | |||
| } | |||
| } else if (this._options.noTransitionAfterReload) { | |||
| $body.addClass('hold-transition').removeClass(CLASS_NAME_COLLAPSED).delay(50).queue(function () { | |||
| $(this).removeClass('hold-transition') | |||
| $(this).dequeue() | |||
| }) | |||
| } else { | |||
| $body.removeClass(CLASS_NAME_COLLAPSED) | |||
| } | |||
| } | |||
| const $body = $('body') | |||
| const toggleState = localStorage.getItem(`remember${EVENT_KEY}`) | |||
| _init() { | |||
| this.remember() | |||
| this.autoCollapse() | |||
| if (toggleState === CLASS_NAME_COLLAPSED) { | |||
| if (this._options.noTransitionAfterReload) { | |||
| $body.addClass('hold-transition').addClass(CLASS_NAME_COLLAPSED).delay(50).queue(function () { | |||
| $(this).removeClass('hold-transition') | |||
| $(this).dequeue() | |||
| $(window).resize(() => { | |||
| this.autoCollapse(true) | |||
| }) | |||
| } else { | |||
| $body.addClass(CLASS_NAME_COLLAPSED) | |||
| } | |||
| } else if (this._options.noTransitionAfterReload) { | |||
| $body.addClass('hold-transition').removeClass(CLASS_NAME_COLLAPSED).delay(50).queue(function () { | |||
| $(this).removeClass('hold-transition') | |||
| $(this).dequeue() | |||
| }) | |||
| } else { | |||
| $body.removeClass(CLASS_NAME_COLLAPSED) | |||
| } | |||
| } | |||
| // Private | |||
| _init() { | |||
| this.remember() | |||
| this.autoCollapse() | |||
| $(window).resize(() => { | |||
| this.autoCollapse(true) | |||
| }) | |||
| } | |||
| // Static | |||
| _addOverlay() { | |||
| const overlay = $('<div />', { | |||
| id: 'sidebar-overlay' | |||
| }) | |||
| overlay.on('click', () => { | |||
| this.collapse() | |||
| }) | |||
| $(SELECTOR_WRAPPER).append(overlay) | |||
| } | |||
| // Static | |||
| static _jQueryInterface(operation) { | |||
| return this.each(function () { | |||
| let data = $(this).data(DATA_KEY) | |||
| const _options = $.extend({}, Default, $(this).data()) | |||
| _addOverlay() { | |||
| const overlay = $('<div />', { | |||
| id: 'sidebar-overlay' | |||
| }) | |||
| if (!data) { | |||
| data = new PushMenu(this, _options) | |||
| $(this).data(DATA_KEY, data) | |||
| } | |||
| overlay.on('click', () => { | |||
| this.collapse() | |||
| }) | |||
| if (typeof operation === 'string' && /collapse|expand|toggle/.test(operation)) { | |||
| data[operation]() | |||
| } | |||
| }) | |||
| } | |||
| $(SELECTOR_WRAPPER).append(overlay) | |||
| } | |||
| } | |||
| /** | |||
| @@ -193,19 +193,19 @@ class PushMenu { | |||
| */ | |||
| $(document).on('click', SELECTOR_TOGGLE_BUTTON, event => { | |||
| event.preventDefault() | |||
| event.preventDefault() | |||
| let button = event.currentTarget | |||
| let button = event.currentTarget | |||
| if ($(button).data('widget') !== 'pushmenu') { | |||
| button = $(button).closest(SELECTOR_TOGGLE_BUTTON) | |||
| } | |||
| if ($(button).data('widget') !== 'pushmenu') { | |||
| button = $(button).closest(SELECTOR_TOGGLE_BUTTON) | |||
| } | |||
| PushMenu._jQueryInterface.call($(button), 'toggle') | |||
| PushMenu._jQueryInterface.call($(button), 'toggle') | |||
| }) | |||
| $(window).on('load', () => { | |||
| PushMenu._jQueryInterface.call($(SELECTOR_TOGGLE_BUTTON)) | |||
| PushMenu._jQueryInterface.call($(SELECTOR_TOGGLE_BUTTON)) | |||
| }) | |||
| /** | |||
| @@ -216,8 +216,8 @@ $(window).on('load', () => { | |||
| $.fn[NAME] = PushMenu._jQueryInterface | |||
| $.fn[NAME].Constructor = PushMenu | |||
| $.fn[NAME].noConflict = function () { | |||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||
| return PushMenu._jQueryInterface | |||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||
| return PushMenu._jQueryInterface | |||
| } | |||
| export default PushMenu | |||
| @@ -5,7 +5,7 @@ | |||
| * -------------------------------------------- | |||
| */ | |||
| import $, { trim } from 'jquery' | |||
| import $, {trim} from 'jquery' | |||
| /** | |||
| * Constants | |||
| @@ -35,13 +35,13 @@ const SELECTOR_SEARCH_RESULTS = `.${CLASS_NAME_SEARCH_RESULTS}` | |||
| const SELECTOR_SEARCH_RESULTS_GROUP = `${SELECTOR_SEARCH_RESULTS} .${CLASS_NAME_LIST_GROUP}` | |||
| const Default = { | |||
| arrowSign: '->', | |||
| minLength: 3, | |||
| maxResults: 7, | |||
| highlightName: true, | |||
| highlightPath: false, | |||
| highlightClass: 'text-light', | |||
| notFoundText: 'No element found!' | |||
| arrowSign: '->', | |||
| minLength: 3, | |||
| maxResults: 7, | |||
| highlightName: true, | |||
| highlightPath: false, | |||
| highlightClass: 'text-light', | |||
| notFoundText: 'No element found!' | |||
| } | |||
| const SearchItems = [] | |||
| @@ -52,179 +52,179 @@ const SearchItems = [] | |||
| */ | |||
| class SidebarSearch { | |||
| constructor(_element, _options) { | |||
| this.element = _element | |||
| this.options = $.extend({}, Default, _options) | |||
| this.items = [] | |||
| } | |||
| // Public | |||
| init() { | |||
| if ($(SELECTOR_DATA_WIDGET).length === 0) { | |||
| return | |||
| constructor(_element, _options) { | |||
| this.element = _element | |||
| this.options = $.extend({}, Default, _options) | |||
| this.items = [] | |||
| } | |||
| if ($(SELECTOR_DATA_WIDGET).next(SELECTOR_SEARCH_RESULTS).length === 0) { | |||
| $(SELECTOR_DATA_WIDGET).after( | |||
| $('<div />', { class: CLASS_NAME_SEARCH_RESULTS }) | |||
| ) | |||
| } | |||
| // Public | |||
| if ($(SELECTOR_SEARCH_RESULTS).children(SELECTOR_SEARCH_LIST_GROUP).length === 0) { | |||
| $(SELECTOR_SEARCH_RESULTS).append( | |||
| $('<div />', { class: CLASS_NAME_LIST_GROUP }) | |||
| ) | |||
| } | |||
| static _jQueryInterface(config) { | |||
| let data = $(this).data(DATA_KEY) | |||
| this._addNotFound() | |||
| if (!data) { | |||
| data = $(this).data() | |||
| } | |||
| $(SELECTOR_SIDEBAR).children().each((i, child) => { | |||
| this._parseItem(child) | |||
| }) | |||
| } | |||
| const _options = $.extend({}, Default, typeof config === 'object' ? config : data) | |||
| const plugin = new SidebarSearch($(this), _options) | |||
| search() { | |||
| const searchValue = $(SELECTOR_SEARCH_INPUT).val().toLowerCase() | |||
| if (searchValue.length < this.options.minLength) { | |||
| $(SELECTOR_SEARCH_RESULTS_GROUP).empty() | |||
| this._addNotFound() | |||
| this.close() | |||
| return | |||
| } | |||
| const searchResults = SearchItems.filter(item => (item.name).toLowerCase().includes(searchValue)) | |||
| const endResults = $(searchResults.slice(0, this.options.maxResults)) | |||
| $(SELECTOR_SEARCH_RESULTS_GROUP).empty() | |||
| $(this).data(DATA_KEY, typeof config === 'object' ? config : data) | |||
| if (endResults.length === 0) { | |||
| this._addNotFound() | |||
| } else { | |||
| endResults.each((i, result) => { | |||
| $(SELECTOR_SEARCH_RESULTS_GROUP).append(this._renderItem(escape(result.name), escape(result.link), result.path)) | |||
| }) | |||
| if (typeof config === 'string' && /init|toggle|close|open|search/.test(config)) { | |||
| plugin[config]() | |||
| } else { | |||
| plugin.init() | |||
| } | |||
| } | |||
| this.open() | |||
| } | |||
| init() { | |||
| if ($(SELECTOR_DATA_WIDGET).length === 0) { | |||
| return | |||
| } | |||
| open() { | |||
| $(SELECTOR_DATA_WIDGET).parent().addClass(CLASS_NAME_OPEN) | |||
| $(SELECTOR_SEARCH_ICON).removeClass(CLASS_NAME_ICON_SEARCH).addClass(CLASS_NAME_ICON_CLOSE) | |||
| } | |||
| if ($(SELECTOR_DATA_WIDGET).next(SELECTOR_SEARCH_RESULTS).length === 0) { | |||
| $(SELECTOR_DATA_WIDGET).after( | |||
| $('<div />', {class: CLASS_NAME_SEARCH_RESULTS}) | |||
| ) | |||
| } | |||
| close() { | |||
| $(SELECTOR_DATA_WIDGET).parent().removeClass(CLASS_NAME_OPEN) | |||
| $(SELECTOR_SEARCH_ICON).removeClass(CLASS_NAME_ICON_CLOSE).addClass(CLASS_NAME_ICON_SEARCH) | |||
| } | |||
| if ($(SELECTOR_SEARCH_RESULTS).children(SELECTOR_SEARCH_LIST_GROUP).length === 0) { | |||
| $(SELECTOR_SEARCH_RESULTS).append( | |||
| $('<div />', {class: CLASS_NAME_LIST_GROUP}) | |||
| ) | |||
| } | |||
| toggle() { | |||
| if ($(SELECTOR_DATA_WIDGET).parent().hasClass(CLASS_NAME_OPEN)) { | |||
| this.close() | |||
| } else { | |||
| this.open() | |||
| } | |||
| } | |||
| this._addNotFound() | |||
| // Private | |||
| _parseItem(item, path = []) { | |||
| if ($(item).hasClass(CLASS_NAME_HEADER)) { | |||
| return | |||
| $(SELECTOR_SIDEBAR).children().each((i, child) => { | |||
| this._parseItem(child) | |||
| }) | |||
| } | |||
| const itemObject = {} | |||
| const navLink = $(item).clone().find(`> ${SELECTOR_NAV_LINK}`) | |||
| const navTreeview = $(item).clone().find(`> ${SELECTOR_NAV_TREEVIEW}`) | |||
| const link = navLink.attr('href') | |||
| const name = navLink.find('p').children().remove().end().text() | |||
| itemObject.name = this._trimText(name) | |||
| itemObject.link = link | |||
| itemObject.path = path | |||
| if (navTreeview.length === 0) { | |||
| SearchItems.push(itemObject) | |||
| } else { | |||
| const newPath = itemObject.path.concat([itemObject.name]) | |||
| navTreeview.children().each((i, child) => { | |||
| this._parseItem(child, newPath) | |||
| }) | |||
| } | |||
| } | |||
| _trimText(text) { | |||
| return trim(text.replace(/(\r\n|\n|\r)/gm, ' ')) | |||
| } | |||
| _renderItem(name, link, path) { | |||
| path = path.join(` ${this.options.arrowSign} `) | |||
| name = unescape(name) | |||
| if (this.options.highlightName || this.options.highlightPath) { | |||
| const searchValue = $(SELECTOR_SEARCH_INPUT).val().toLowerCase() | |||
| const regExp = new RegExp(searchValue, 'gi') | |||
| if (this.options.highlightName) { | |||
| name = name.replace( | |||
| regExp, | |||
| str => { | |||
| return `<strong class="${this.options.highlightClass}">${str}</strong>` | |||
| } | |||
| ) | |||
| } | |||
| if (this.options.highlightPath) { | |||
| path = path.replace( | |||
| regExp, | |||
| str => { | |||
| return `<strong class="${this.options.highlightClass}">${str}</strong>` | |||
| } | |||
| ) | |||
| } | |||
| search() { | |||
| const searchValue = $(SELECTOR_SEARCH_INPUT).val().toLowerCase() | |||
| if (searchValue.length < this.options.minLength) { | |||
| $(SELECTOR_SEARCH_RESULTS_GROUP).empty() | |||
| this._addNotFound() | |||
| this.close() | |||
| return | |||
| } | |||
| const searchResults = SearchItems.filter(item => (item.name).toLowerCase().includes(searchValue)) | |||
| const endResults = $(searchResults.slice(0, this.options.maxResults)) | |||
| $(SELECTOR_SEARCH_RESULTS_GROUP).empty() | |||
| if (endResults.length === 0) { | |||
| this._addNotFound() | |||
| } else { | |||
| endResults.each((i, result) => { | |||
| $(SELECTOR_SEARCH_RESULTS_GROUP).append(this._renderItem(escape(result.name), escape(result.link), result.path)) | |||
| }) | |||
| } | |||
| this.open() | |||
| } | |||
| const groupItemElement = $('<a/>', { | |||
| href: link, | |||
| class: 'list-group-item' | |||
| }) | |||
| const searchTitleElement = $('<div/>', { | |||
| class: 'search-title' | |||
| }).html(name) | |||
| const searchPathElement = $('<div/>', { | |||
| class: 'search-path' | |||
| }).html(path) | |||
| groupItemElement.append(searchTitleElement).append(searchPathElement) | |||
| open() { | |||
| $(SELECTOR_DATA_WIDGET).parent().addClass(CLASS_NAME_OPEN) | |||
| $(SELECTOR_SEARCH_ICON).removeClass(CLASS_NAME_ICON_SEARCH).addClass(CLASS_NAME_ICON_CLOSE) | |||
| } | |||
| return groupItemElement | |||
| } | |||
| close() { | |||
| $(SELECTOR_DATA_WIDGET).parent().removeClass(CLASS_NAME_OPEN) | |||
| $(SELECTOR_SEARCH_ICON).removeClass(CLASS_NAME_ICON_CLOSE).addClass(CLASS_NAME_ICON_SEARCH) | |||
| } | |||
| _addNotFound() { | |||
| $(SELECTOR_SEARCH_RESULTS_GROUP).append(this._renderItem(this.options.notFoundText, '#', [])) | |||
| } | |||
| // Private | |||
| // Static | |||
| toggle() { | |||
| if ($(SELECTOR_DATA_WIDGET).parent().hasClass(CLASS_NAME_OPEN)) { | |||
| this.close() | |||
| } else { | |||
| this.open() | |||
| } | |||
| } | |||
| static _jQueryInterface(config) { | |||
| let data = $(this).data(DATA_KEY) | |||
| _parseItem(item, path = []) { | |||
| if ($(item).hasClass(CLASS_NAME_HEADER)) { | |||
| return | |||
| } | |||
| const itemObject = {} | |||
| const navLink = $(item).clone().find(`> ${SELECTOR_NAV_LINK}`) | |||
| const navTreeview = $(item).clone().find(`> ${SELECTOR_NAV_TREEVIEW}`) | |||
| const link = navLink.attr('href') | |||
| const name = navLink.find('p').children().remove().end().text() | |||
| itemObject.name = this._trimText(name) | |||
| itemObject.link = link | |||
| itemObject.path = path | |||
| if (navTreeview.length === 0) { | |||
| SearchItems.push(itemObject) | |||
| } else { | |||
| const newPath = itemObject.path.concat([itemObject.name]) | |||
| navTreeview.children().each((i, child) => { | |||
| this._parseItem(child, newPath) | |||
| }) | |||
| } | |||
| } | |||
| if (!data) { | |||
| data = $(this).data() | |||
| _trimText(text) { | |||
| return trim(text.replace(/(\r\n|\n|\r)/gm, ' ')) | |||
| } | |||
| const _options = $.extend({}, Default, typeof config === 'object' ? config : data) | |||
| const plugin = new SidebarSearch($(this), _options) | |||
| _renderItem(name, link, path) { | |||
| path = path.join(` ${this.options.arrowSign} `) | |||
| name = unescape(name) | |||
| if (this.options.highlightName || this.options.highlightPath) { | |||
| const searchValue = $(SELECTOR_SEARCH_INPUT).val().toLowerCase() | |||
| const regExp = new RegExp(searchValue, 'gi') | |||
| if (this.options.highlightName) { | |||
| name = name.replace( | |||
| regExp, | |||
| str => { | |||
| return `<strong class="${this.options.highlightClass}">${str}</strong>` | |||
| } | |||
| ) | |||
| } | |||
| if (this.options.highlightPath) { | |||
| path = path.replace( | |||
| regExp, | |||
| str => { | |||
| return `<strong class="${this.options.highlightClass}">${str}</strong>` | |||
| } | |||
| ) | |||
| } | |||
| } | |||
| const groupItemElement = $('<a/>', { | |||
| href: link, | |||
| class: 'list-group-item' | |||
| }) | |||
| const searchTitleElement = $('<div/>', { | |||
| class: 'search-title' | |||
| }).html(name) | |||
| const searchPathElement = $('<div/>', { | |||
| class: 'search-path' | |||
| }).html(path) | |||
| groupItemElement.append(searchTitleElement).append(searchPathElement) | |||
| return groupItemElement | |||
| } | |||
| $(this).data(DATA_KEY, typeof config === 'object' ? config : data) | |||
| // Static | |||
| if (typeof config === 'string' && /init|toggle|close|open|search/.test(config)) { | |||
| plugin[config]() | |||
| } else { | |||
| plugin.init() | |||
| _addNotFound() { | |||
| $(SELECTOR_SEARCH_RESULTS_GROUP).append(this._renderItem(this.options.notFoundText, '#', [])) | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| @@ -232,55 +232,55 @@ class SidebarSearch { | |||
| * ==================================================== | |||
| */ | |||
| $(document).on('click', SELECTOR_SEARCH_BUTTON, event => { | |||
| event.preventDefault() | |||
| event.preventDefault() | |||
| SidebarSearch._jQueryInterface.call($(SELECTOR_DATA_WIDGET), 'toggle') | |||
| SidebarSearch._jQueryInterface.call($(SELECTOR_DATA_WIDGET), 'toggle') | |||
| }) | |||
| $(document).on('keyup', SELECTOR_SEARCH_INPUT, event => { | |||
| if (event.keyCode == 38) { | |||
| event.preventDefault() | |||
| $(SELECTOR_SEARCH_RESULTS_GROUP).children().last().focus() | |||
| return | |||
| } | |||
| if (event.keyCode == 38) { | |||
| event.preventDefault() | |||
| $(SELECTOR_SEARCH_RESULTS_GROUP).children().last().focus() | |||
| return | |||
| } | |||
| if (event.keyCode == 40) { | |||
| event.preventDefault() | |||
| $(SELECTOR_SEARCH_RESULTS_GROUP).children().first().focus() | |||
| return | |||
| } | |||
| if (event.keyCode == 40) { | |||
| event.preventDefault() | |||
| $(SELECTOR_SEARCH_RESULTS_GROUP).children().first().focus() | |||
| return | |||
| } | |||
| setTimeout(() => { | |||
| SidebarSearch._jQueryInterface.call($(SELECTOR_DATA_WIDGET), 'search') | |||
| }, 100) | |||
| setTimeout(() => { | |||
| SidebarSearch._jQueryInterface.call($(SELECTOR_DATA_WIDGET), 'search') | |||
| }, 100) | |||
| }) | |||
| $(document).on('keydown', SELECTOR_SEARCH_RESULTS_GROUP, event => { | |||
| const $focused = $(':focus') | |||
| const $focused = $(':focus') | |||
| if (event.keyCode == 38) { | |||
| event.preventDefault() | |||
| if (event.keyCode == 38) { | |||
| event.preventDefault() | |||
| if ($focused.is(':first-child')) { | |||
| $focused.siblings().last().focus() | |||
| } else { | |||
| $focused.prev().focus() | |||
| if ($focused.is(':first-child')) { | |||
| $focused.siblings().last().focus() | |||
| } else { | |||
| $focused.prev().focus() | |||
| } | |||
| } | |||
| } | |||
| if (event.keyCode == 40) { | |||
| event.preventDefault() | |||
| if (event.keyCode == 40) { | |||
| event.preventDefault() | |||
| if ($focused.is(':last-child')) { | |||
| $focused.siblings().first().focus() | |||
| } else { | |||
| $focused.next().focus() | |||
| if ($focused.is(':last-child')) { | |||
| $focused.siblings().first().focus() | |||
| } else { | |||
| $focused.next().focus() | |||
| } | |||
| } | |||
| } | |||
| }) | |||
| $(window).on('load', () => { | |||
| SidebarSearch._jQueryInterface.call($(SELECTOR_DATA_WIDGET), 'init') | |||
| SidebarSearch._jQueryInterface.call($(SELECTOR_DATA_WIDGET), 'init') | |||
| }) | |||
| /** | |||
| @@ -291,8 +291,8 @@ $(window).on('load', () => { | |||
| $.fn[NAME] = SidebarSearch._jQueryInterface | |||
| $.fn[NAME].Constructor = SidebarSearch | |||
| $.fn[NAME].noConflict = function () { | |||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||
| return SidebarSearch._jQueryInterface | |||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||
| return SidebarSearch._jQueryInterface | |||
| } | |||
| export default SidebarSearch | |||
| @@ -37,21 +37,21 @@ const POSITION_BOTTOM_RIGHT = 'bottomRight' | |||
| const POSITION_BOTTOM_LEFT = 'bottomLeft' | |||
| const Default = { | |||
| position: POSITION_TOP_RIGHT, | |||
| fixed: true, | |||
| autohide: false, | |||
| autoremove: true, | |||
| delay: 1000, | |||
| fade: true, | |||
| icon: null, | |||
| image: null, | |||
| imageAlt: null, | |||
| imageHeight: '25px', | |||
| title: null, | |||
| subtitle: null, | |||
| close: true, | |||
| body: null, | |||
| class: null | |||
| position: POSITION_TOP_RIGHT, | |||
| fixed: true, | |||
| autohide: false, | |||
| autoremove: true, | |||
| delay: 1000, | |||
| fade: true, | |||
| icon: null, | |||
| image: null, | |||
| imageAlt: null, | |||
| imageHeight: '25px', | |||
| title: null, | |||
| subtitle: null, | |||
| close: true, | |||
| body: null, | |||
| class: null | |||
| } | |||
| /** | |||
| @@ -59,139 +59,139 @@ const Default = { | |||
| * ==================================================== | |||
| */ | |||
| class Toasts { | |||
| constructor(element, config) { | |||
| this._config = config | |||
| this._prepareContainer() | |||
| constructor(element, config) { | |||
| this._config = config | |||
| this._prepareContainer() | |||
| $('body').trigger($.Event(EVENT_INIT)) | |||
| } | |||
| // Public | |||
| $('body').trigger($.Event(EVENT_INIT)) | |||
| } | |||
| create() { | |||
| const toast = $('<div class="toast" role="alert" aria-live="assertive" aria-atomic="true"/>') | |||
| // Public | |||
| toast.data('autohide', this._config.autohide) | |||
| toast.data('animation', this._config.fade) | |||
| static _jQueryInterface(option, config) { | |||
| return this.each(function () { | |||
| const _options = $.extend({}, Default, config) | |||
| const toast = new Toasts($(this), _options) | |||
| if (this._config.class) { | |||
| toast.addClass(this._config.class) | |||
| if (option === 'create') { | |||
| toast[option]() | |||
| } | |||
| }) | |||
| } | |||
| if (this._config.delay && this._config.delay != 500) { | |||
| toast.data('delay', this._config.delay) | |||
| } | |||
| // Static | |||
| const toastHeader = $('<div class="toast-header">') | |||
| create() { | |||
| const toast = $('<div class="toast" role="alert" aria-live="assertive" aria-atomic="true"/>') | |||
| if (this._config.image != null) { | |||
| const toastImage = $('<img />').addClass('rounded mr-2').attr('src', this._config.image).attr('alt', this._config.imageAlt) | |||
| toast.data('autohide', this._config.autohide) | |||
| toast.data('animation', this._config.fade) | |||
| if (this._config.imageHeight != null) { | |||
| toastImage.height(this._config.imageHeight).width('auto') | |||
| } | |||
| if (this._config.class) { | |||
| toast.addClass(this._config.class) | |||
| } | |||
| toastHeader.append(toastImage) | |||
| } | |||
| if (this._config.delay && this._config.delay != 500) { | |||
| toast.data('delay', this._config.delay) | |||
| } | |||
| if (this._config.icon != null) { | |||
| toastHeader.append($('<i />').addClass('mr-2').addClass(this._config.icon)) | |||
| } | |||
| const toastHeader = $('<div class="toast-header">') | |||
| if (this._config.title != null) { | |||
| toastHeader.append($('<strong />').addClass('mr-auto').html(this._config.title)) | |||
| } | |||
| if (this._config.image != null) { | |||
| const toastImage = $('<img />').addClass('rounded mr-2').attr('src', this._config.image).attr('alt', this._config.imageAlt) | |||
| if (this._config.subtitle != null) { | |||
| toastHeader.append($('<small />').html(this._config.subtitle)) | |||
| } | |||
| if (this._config.imageHeight != null) { | |||
| toastImage.height(this._config.imageHeight).width('auto') | |||
| } | |||
| if (this._config.close == true) { | |||
| const toastClose = $('<button data-dismiss="toast" />').attr('type', 'button').addClass('ml-2 mb-1 close').attr('aria-label', 'Close').append('<span aria-hidden="true">×</span>') | |||
| toastHeader.append(toastImage) | |||
| } | |||
| if (this._config.title == null) { | |||
| toastClose.toggleClass('ml-2 ml-auto') | |||
| } | |||
| if (this._config.icon != null) { | |||
| toastHeader.append($('<i />').addClass('mr-2').addClass(this._config.icon)) | |||
| } | |||
| toastHeader.append(toastClose) | |||
| } | |||
| if (this._config.title != null) { | |||
| toastHeader.append($('<strong />').addClass('mr-auto').html(this._config.title)) | |||
| } | |||
| toast.append(toastHeader) | |||
| if (this._config.subtitle != null) { | |||
| toastHeader.append($('<small />').html(this._config.subtitle)) | |||
| } | |||
| if (this._config.body != null) { | |||
| toast.append($('<div class="toast-body" />').html(this._config.body)) | |||
| } | |||
| if (this._config.close == true) { | |||
| const toastClose = $('<button data-dismiss="toast" />').attr('type', 'button').addClass('ml-2 mb-1 close').attr('aria-label', 'Close').append('<span aria-hidden="true">×</span>') | |||
| $(this._getContainerId()).prepend(toast) | |||
| if (this._config.title == null) { | |||
| toastClose.toggleClass('ml-2 ml-auto') | |||
| } | |||
| const $body = $('body') | |||
| toastHeader.append(toastClose) | |||
| } | |||
| $body.trigger($.Event(EVENT_CREATED)) | |||
| toast.toast('show') | |||
| toast.append(toastHeader) | |||
| if (this._config.autoremove) { | |||
| toast.on('hidden.bs.toast', function () { | |||
| $(this).delay(200).remove() | |||
| $body.trigger($.Event(EVENT_REMOVED)) | |||
| }) | |||
| } | |||
| } | |||
| if (this._config.body != null) { | |||
| toast.append($('<div class="toast-body" />').html(this._config.body)) | |||
| } | |||
| // Static | |||
| $(this._getContainerId()).prepend(toast) | |||
| _getContainerId() { | |||
| if (this._config.position == POSITION_TOP_RIGHT) { | |||
| return SELECTOR_CONTAINER_TOP_RIGHT | |||
| } | |||
| const $body = $('body') | |||
| if (this._config.position == POSITION_TOP_LEFT) { | |||
| return SELECTOR_CONTAINER_TOP_LEFT | |||
| } | |||
| $body.trigger($.Event(EVENT_CREATED)) | |||
| toast.toast('show') | |||
| if (this._config.position == POSITION_BOTTOM_RIGHT) { | |||
| return SELECTOR_CONTAINER_BOTTOM_RIGHT | |||
| if (this._config.autoremove) { | |||
| toast.on('hidden.bs.toast', function () { | |||
| $(this).delay(200).remove() | |||
| $body.trigger($.Event(EVENT_REMOVED)) | |||
| }) | |||
| } | |||
| } | |||
| if (this._config.position == POSITION_BOTTOM_LEFT) { | |||
| return SELECTOR_CONTAINER_BOTTOM_LEFT | |||
| } | |||
| } | |||
| _prepareContainer() { | |||
| if ($(this._getContainerId()).length === 0) { | |||
| const container = $('<div />').attr('id', this._getContainerId().replace('#', '')) | |||
| if (this._config.position == POSITION_TOP_RIGHT) { | |||
| container.addClass(CLASS_NAME_TOP_RIGHT) | |||
| } else if (this._config.position == POSITION_TOP_LEFT) { | |||
| container.addClass(CLASS_NAME_TOP_LEFT) | |||
| } else if (this._config.position == POSITION_BOTTOM_RIGHT) { | |||
| container.addClass(CLASS_NAME_BOTTOM_RIGHT) | |||
| } else if (this._config.position == POSITION_BOTTOM_LEFT) { | |||
| container.addClass(CLASS_NAME_BOTTOM_LEFT) | |||
| } | |||
| $('body').append(container) | |||
| } | |||
| _getContainerId() { | |||
| if (this._config.position == POSITION_TOP_RIGHT) { | |||
| return SELECTOR_CONTAINER_TOP_RIGHT | |||
| } | |||
| if (this._config.fixed) { | |||
| $(this._getContainerId()).addClass('fixed') | |||
| } else { | |||
| $(this._getContainerId()).removeClass('fixed') | |||
| } | |||
| } | |||
| if (this._config.position == POSITION_TOP_LEFT) { | |||
| return SELECTOR_CONTAINER_TOP_LEFT | |||
| } | |||
| // Static | |||
| if (this._config.position == POSITION_BOTTOM_RIGHT) { | |||
| return SELECTOR_CONTAINER_BOTTOM_RIGHT | |||
| } | |||
| static _jQueryInterface(option, config) { | |||
| return this.each(function () { | |||
| const _options = $.extend({}, Default, config) | |||
| const toast = new Toasts($(this), _options) | |||
| if (this._config.position == POSITION_BOTTOM_LEFT) { | |||
| return SELECTOR_CONTAINER_BOTTOM_LEFT | |||
| } | |||
| } | |||
| if (option === 'create') { | |||
| toast[option]() | |||
| } | |||
| }) | |||
| } | |||
| // Static | |||
| _prepareContainer() { | |||
| if ($(this._getContainerId()).length === 0) { | |||
| const container = $('<div />').attr('id', this._getContainerId().replace('#', '')) | |||
| if (this._config.position == POSITION_TOP_RIGHT) { | |||
| container.addClass(CLASS_NAME_TOP_RIGHT) | |||
| } else if (this._config.position == POSITION_TOP_LEFT) { | |||
| container.addClass(CLASS_NAME_TOP_LEFT) | |||
| } else if (this._config.position == POSITION_BOTTOM_RIGHT) { | |||
| container.addClass(CLASS_NAME_BOTTOM_RIGHT) | |||
| } else if (this._config.position == POSITION_BOTTOM_LEFT) { | |||
| container.addClass(CLASS_NAME_BOTTOM_LEFT) | |||
| } | |||
| $('body').append(container) | |||
| } | |||
| if (this._config.fixed) { | |||
| $(this._getContainerId()).addClass('fixed') | |||
| } else { | |||
| $(this._getContainerId()).removeClass('fixed') | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| @@ -202,8 +202,8 @@ class Toasts { | |||
| $.fn[NAME] = Toasts._jQueryInterface | |||
| $.fn[NAME].Constructor = Toasts | |||
| $.fn[NAME].noConflict = function () { | |||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||
| return Toasts._jQueryInterface | |||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||
| return Toasts._jQueryInterface | |||
| } | |||
| export default Toasts | |||
| @@ -20,12 +20,12 @@ const SELECTOR_DATA_TOGGLE = '[data-widget="todo-list"]' | |||
| const CLASS_NAME_TODO_LIST_DONE = 'done' | |||
| const Default = { | |||
| onCheck(item) { | |||
| return item | |||
| }, | |||
| onUnCheck(item) { | |||
| return item | |||
| } | |||
| onCheck(item) { | |||
| return item | |||
| }, | |||
| onUnCheck(item) { | |||
| return item | |||
| } | |||
| } | |||
| /** | |||
| @@ -34,64 +34,64 @@ const Default = { | |||
| */ | |||
| class TodoList { | |||
| constructor(element, config) { | |||
| this._config = config | |||
| this._element = element | |||
| constructor(element, config) { | |||
| this._config = config | |||
| this._element = element | |||
| this._init() | |||
| } | |||
| this._init() | |||
| } | |||
| // Public | |||
| // Public | |||
| toggle(item) { | |||
| item.parents('li').toggleClass(CLASS_NAME_TODO_LIST_DONE) | |||
| if (!$(item).prop('checked')) { | |||
| this.unCheck($(item)) | |||
| return | |||
| } | |||
| static _jQueryInterface(config) { | |||
| return this.each(function () { | |||
| let data = $(this).data(DATA_KEY) | |||
| this.check(item) | |||
| } | |||
| if (!data) { | |||
| data = $(this).data() | |||
| } | |||
| check(item) { | |||
| this._config.onCheck.call(item) | |||
| } | |||
| const _options = $.extend({}, Default, typeof config === 'object' ? config : data) | |||
| const plugin = new TodoList($(this), _options) | |||
| unCheck(item) { | |||
| this._config.onUnCheck.call(item) | |||
| } | |||
| $(this).data(DATA_KEY, typeof config === 'object' ? config : data) | |||
| // Private | |||
| if (config === 'init') { | |||
| plugin[config]() | |||
| } | |||
| }) | |||
| } | |||
| _init() { | |||
| const $toggleSelector = this._element | |||
| toggle(item) { | |||
| item.parents('li').toggleClass(CLASS_NAME_TODO_LIST_DONE) | |||
| if (!$(item).prop('checked')) { | |||
| this.unCheck($(item)) | |||
| return | |||
| } | |||
| $toggleSelector.find('input:checkbox:checked').parents('li').toggleClass(CLASS_NAME_TODO_LIST_DONE) | |||
| $toggleSelector.on('change', 'input:checkbox', event => { | |||
| this.toggle($(event.target)) | |||
| }) | |||
| } | |||
| this.check(item) | |||
| } | |||
| // Static | |||
| check(item) { | |||
| this._config.onCheck.call(item) | |||
| } | |||
| static _jQueryInterface(config) { | |||
| return this.each(function () { | |||
| let data = $(this).data(DATA_KEY) | |||
| // Private | |||
| if (!data) { | |||
| data = $(this).data() | |||
| } | |||
| unCheck(item) { | |||
| this._config.onUnCheck.call(item) | |||
| } | |||
| const _options = $.extend({}, Default, typeof config === 'object' ? config : data) | |||
| const plugin = new TodoList($(this), _options) | |||
| // Static | |||
| $(this).data(DATA_KEY, typeof config === 'object' ? config : data) | |||
| _init() { | |||
| const $toggleSelector = this._element | |||
| if (config === 'init') { | |||
| plugin[config]() | |||
| } | |||
| }) | |||
| } | |||
| $toggleSelector.find('input:checkbox:checked').parents('li').toggleClass(CLASS_NAME_TODO_LIST_DONE) | |||
| $toggleSelector.on('change', 'input:checkbox', event => { | |||
| this.toggle($(event.target)) | |||
| }) | |||
| } | |||
| } | |||
| /** | |||
| @@ -100,7 +100,7 @@ class TodoList { | |||
| */ | |||
| $(window).on('load', () => { | |||
| TodoList._jQueryInterface.call($(SELECTOR_DATA_TOGGLE)) | |||
| TodoList._jQueryInterface.call($(SELECTOR_DATA_TOGGLE)) | |||
| }) | |||
| /** | |||
| @@ -111,8 +111,8 @@ $(window).on('load', () => { | |||
| $.fn[NAME] = TodoList._jQueryInterface | |||
| $.fn[NAME].Constructor = TodoList | |||
| $.fn[NAME].noConflict = function () { | |||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||
| return TodoList._jQueryInterface | |||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||
| return TodoList._jQueryInterface | |||
| } | |||
| export default TodoList | |||
| @@ -32,11 +32,11 @@ const CLASS_NAME_IS_OPENING = 'menu-is-opening' | |||
| const CLASS_NAME_SIDEBAR_COLLAPSED = 'sidebar-collapse' | |||
| const Default = { | |||
| trigger: `${SELECTOR_DATA_WIDGET} ${SELECTOR_LINK}`, | |||
| animationSpeed: 300, | |||
| accordion: true, | |||
| expandSidebar: false, | |||
| sidebarButtonSelector: '[data-widget="pushmenu"]' | |||
| trigger: `${SELECTOR_DATA_WIDGET} ${SELECTOR_LINK}`, | |||
| animationSpeed: 300, | |||
| accordion: true, | |||
| expandSidebar: false, | |||
| sidebarButtonSelector: '[data-widget="pushmenu"]' | |||
| } | |||
| /** | |||
| @@ -44,109 +44,109 @@ const Default = { | |||
| * ==================================================== | |||
| */ | |||
| class Treeview { | |||
| constructor(element, config) { | |||
| this._config = config | |||
| this._element = element | |||
| } | |||
| constructor(element, config) { | |||
| this._config = config | |||
| this._element = element | |||
| } | |||
| // Public | |||
| // Public | |||
| init() { | |||
| $(`${SELECTOR_LI}${SELECTOR_OPEN} ${SELECTOR_TREEVIEW_MENU}${SELECTOR_OPEN}`).css('display', 'block') | |||
| this._setupListeners() | |||
| } | |||
| static _jQueryInterface(config) { | |||
| return this.each(function () { | |||
| let data = $(this).data(DATA_KEY) | |||
| const _options = $.extend({}, Default, $(this).data()) | |||
| expand(treeviewMenu, parentLi) { | |||
| const expandedEvent = $.Event(EVENT_EXPANDED) | |||
| if (!data) { | |||
| data = new Treeview($(this), _options) | |||
| $(this).data(DATA_KEY, data) | |||
| } | |||
| if (this._config.accordion) { | |||
| const openMenuLi = parentLi.siblings(SELECTOR_OPEN).first() | |||
| const openTreeview = openMenuLi.find(SELECTOR_TREEVIEW_MENU).first() | |||
| this.collapse(openTreeview, openMenuLi) | |||
| if (config === 'init') { | |||
| data[config]() | |||
| } | |||
| }) | |||
| } | |||
| parentLi.addClass(CLASS_NAME_IS_OPENING) | |||
| treeviewMenu.stop().slideDown(this._config.animationSpeed, () => { | |||
| parentLi.addClass(CLASS_NAME_OPEN) | |||
| $(this._element).trigger(expandedEvent) | |||
| }) | |||
| if (this._config.expandSidebar) { | |||
| this._expandSidebar() | |||
| init() { | |||
| $(`${SELECTOR_LI}${SELECTOR_OPEN} ${SELECTOR_TREEVIEW_MENU}${SELECTOR_OPEN}`).css('display', 'block') | |||
| this._setupListeners() | |||
| } | |||
| } | |||
| collapse(treeviewMenu, parentLi) { | |||
| const collapsedEvent = $.Event(EVENT_COLLAPSED) | |||
| expand(treeviewMenu, parentLi) { | |||
| const expandedEvent = $.Event(EVENT_EXPANDED) | |||
| parentLi.removeClass(`${CLASS_NAME_IS_OPENING} ${CLASS_NAME_OPEN}`) | |||
| treeviewMenu.stop().slideUp(this._config.animationSpeed, () => { | |||
| $(this._element).trigger(collapsedEvent) | |||
| treeviewMenu.find(`${SELECTOR_OPEN} > ${SELECTOR_TREEVIEW_MENU}`).slideUp() | |||
| treeviewMenu.find(SELECTOR_OPEN).removeClass(CLASS_NAME_OPEN) | |||
| }) | |||
| } | |||
| if (this._config.accordion) { | |||
| const openMenuLi = parentLi.siblings(SELECTOR_OPEN).first() | |||
| const openTreeview = openMenuLi.find(SELECTOR_TREEVIEW_MENU).first() | |||
| this.collapse(openTreeview, openMenuLi) | |||
| } | |||
| toggle(event) { | |||
| const $relativeTarget = $(event.currentTarget) | |||
| const $parent = $relativeTarget.parent() | |||
| parentLi.addClass(CLASS_NAME_IS_OPENING) | |||
| treeviewMenu.stop().slideDown(this._config.animationSpeed, () => { | |||
| parentLi.addClass(CLASS_NAME_OPEN) | |||
| $(this._element).trigger(expandedEvent) | |||
| }) | |||
| let treeviewMenu = $parent.find(`> ${SELECTOR_TREEVIEW_MENU}`) | |||
| if (this._config.expandSidebar) { | |||
| this._expandSidebar() | |||
| } | |||
| } | |||
| if (!treeviewMenu.is(SELECTOR_TREEVIEW_MENU)) { | |||
| if (!$parent.is(SELECTOR_LI)) { | |||
| treeviewMenu = $parent.parent().find(`> ${SELECTOR_TREEVIEW_MENU}`) | |||
| } | |||
| collapse(treeviewMenu, parentLi) { | |||
| const collapsedEvent = $.Event(EVENT_COLLAPSED) | |||
| if (!treeviewMenu.is(SELECTOR_TREEVIEW_MENU)) { | |||
| return | |||
| } | |||
| parentLi.removeClass(`${CLASS_NAME_IS_OPENING} ${CLASS_NAME_OPEN}`) | |||
| treeviewMenu.stop().slideUp(this._config.animationSpeed, () => { | |||
| $(this._element).trigger(collapsedEvent) | |||
| treeviewMenu.find(`${SELECTOR_OPEN} > ${SELECTOR_TREEVIEW_MENU}`).slideUp() | |||
| treeviewMenu.find(SELECTOR_OPEN).removeClass(CLASS_NAME_OPEN) | |||
| }) | |||
| } | |||
| event.preventDefault() | |||
| // Private | |||
| const parentLi = $relativeTarget.parents(SELECTOR_LI).first() | |||
| const isOpen = parentLi.hasClass(CLASS_NAME_OPEN) | |||
| toggle(event) { | |||
| const $relativeTarget = $(event.currentTarget) | |||
| const $parent = $relativeTarget.parent() | |||
| if (isOpen) { | |||
| this.collapse($(treeviewMenu), parentLi) | |||
| } else { | |||
| this.expand($(treeviewMenu), parentLi) | |||
| } | |||
| } | |||
| let treeviewMenu = $parent.find(`> ${SELECTOR_TREEVIEW_MENU}`) | |||
| // Private | |||
| if (!treeviewMenu.is(SELECTOR_TREEVIEW_MENU)) { | |||
| if (!$parent.is(SELECTOR_LI)) { | |||
| treeviewMenu = $parent.parent().find(`> ${SELECTOR_TREEVIEW_MENU}`) | |||
| } | |||
| _setupListeners() { | |||
| const elementId = this._element.attr('id') !== undefined ? `#${this._element.attr('id')}` : '' | |||
| $(document).on('click', `${elementId}${this._config.trigger}`, event => { | |||
| this.toggle(event) | |||
| }) | |||
| } | |||
| if (!treeviewMenu.is(SELECTOR_TREEVIEW_MENU)) { | |||
| return | |||
| } | |||
| } | |||
| _expandSidebar() { | |||
| if ($('body').hasClass(CLASS_NAME_SIDEBAR_COLLAPSED)) { | |||
| $(this._config.sidebarButtonSelector).PushMenu('expand') | |||
| } | |||
| } | |||
| event.preventDefault() | |||
| // Static | |||
| const parentLi = $relativeTarget.parents(SELECTOR_LI).first() | |||
| const isOpen = parentLi.hasClass(CLASS_NAME_OPEN) | |||
| static _jQueryInterface(config) { | |||
| return this.each(function () { | |||
| let data = $(this).data(DATA_KEY) | |||
| const _options = $.extend({}, Default, $(this).data()) | |||
| if (isOpen) { | |||
| this.collapse($(treeviewMenu), parentLi) | |||
| } else { | |||
| this.expand($(treeviewMenu), parentLi) | |||
| } | |||
| } | |||
| if (!data) { | |||
| data = new Treeview($(this), _options) | |||
| $(this).data(DATA_KEY, data) | |||
| } | |||
| _setupListeners() { | |||
| const elementId = this._element.attr('id') !== undefined ? `#${this._element.attr('id')}` : '' | |||
| $(document).on('click', `${elementId}${this._config.trigger}`, event => { | |||
| this.toggle(event) | |||
| }) | |||
| } | |||
| if (config === 'init') { | |||
| data[config]() | |||
| } | |||
| }) | |||
| } | |||
| // Static | |||
| _expandSidebar() { | |||
| if ($('body').hasClass(CLASS_NAME_SIDEBAR_COLLAPSED)) { | |||
| $(this._config.sidebarButtonSelector).PushMenu('expand') | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| @@ -155,9 +155,9 @@ class Treeview { | |||
| */ | |||
| $(window).on(EVENT_LOAD_DATA_API, () => { | |||
| $(SELECTOR_DATA_WIDGET).each(function () { | |||
| Treeview._jQueryInterface.call($(this), 'init') | |||
| }) | |||
| $(SELECTOR_DATA_WIDGET).each(function () { | |||
| Treeview._jQueryInterface.call($(this), 'init') | |||
| }) | |||
| }) | |||
| /** | |||
| @@ -168,8 +168,8 @@ $(window).on(EVENT_LOAD_DATA_API, () => { | |||
| $.fn[NAME] = Treeview._jQueryInterface | |||
| $.fn[NAME].Constructor = Treeview | |||
| $.fn[NAME].noConflict = function () { | |||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||
| return Treeview._jQueryInterface | |||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||
| return Treeview._jQueryInterface | |||
| } | |||
| export default Treeview | |||
| @@ -1,48 +1,48 @@ | |||
| 'use strict' | |||
| const Plugins = [ | |||
| // AdminLTE Dist | |||
| { | |||
| from: 'dist/css/', | |||
| to: 'docs/assets/css/' | |||
| }, | |||
| { | |||
| from: 'dist/js/', | |||
| to: 'docs/assets/js/' | |||
| }, | |||
| // jQuery | |||
| { | |||
| from: 'node_modules/jquery/dist/', | |||
| to: 'docs/assets/plugins/jquery/' | |||
| }, | |||
| // Popper | |||
| { | |||
| from: 'node_modules/popper.js/dist/', | |||
| to: 'docs/assets/plugins/popper/' | |||
| }, | |||
| // Bootstrap | |||
| { | |||
| from: 'node_modules/bootstrap/dist/js/', | |||
| to: 'docs/assets/plugins/bootstrap/js/' | |||
| }, | |||
| // Font Awesome | |||
| { | |||
| from: 'node_modules/@fortawesome/fontawesome-free/css/', | |||
| to: 'docs/assets/plugins/fontawesome-free/css/' | |||
| }, | |||
| { | |||
| from: 'node_modules/@fortawesome/fontawesome-free/webfonts/', | |||
| to: 'docs/assets/plugins/fontawesome-free/webfonts/' | |||
| }, | |||
| // overlayScrollbars | |||
| { | |||
| from: 'node_modules/overlayscrollbars/js/', | |||
| to: 'docs/assets/plugins/overlayScrollbars/js/' | |||
| }, | |||
| { | |||
| from: 'node_modules/overlayscrollbars/css/', | |||
| to: 'docs/assets/plugins/overlayScrollbars/css/' | |||
| } | |||
| // AdminLTE Dist | |||
| { | |||
| from: 'dist/css/', | |||
| to: 'docs/assets/css/' | |||
| }, | |||
| { | |||
| from: 'dist/js/', | |||
| to: 'docs/assets/js/' | |||
| }, | |||
| // jQuery | |||
| { | |||
| from: 'node_modules/jquery/dist/', | |||
| to: 'docs/assets/plugins/jquery/' | |||
| }, | |||
| // Popper | |||
| { | |||
| from: 'node_modules/popper.js/dist/', | |||
| to: 'docs/assets/plugins/popper/' | |||
| }, | |||
| // Bootstrap | |||
| { | |||
| from: 'node_modules/bootstrap/dist/js/', | |||
| to: 'docs/assets/plugins/bootstrap/js/' | |||
| }, | |||
| // Font Awesome | |||
| { | |||
| from: 'node_modules/@fortawesome/fontawesome-free/css/', | |||
| to: 'docs/assets/plugins/fontawesome-free/css/' | |||
| }, | |||
| { | |||
| from: 'node_modules/@fortawesome/fontawesome-free/webfonts/', | |||
| to: 'docs/assets/plugins/fontawesome-free/webfonts/' | |||
| }, | |||
| // overlayScrollbars | |||
| { | |||
| from: 'node_modules/overlayscrollbars/js/', | |||
| to: 'docs/assets/plugins/overlayScrollbars/js/' | |||
| }, | |||
| { | |||
| from: 'node_modules/overlayscrollbars/css/', | |||
| to: 'docs/assets/plugins/overlayScrollbars/css/' | |||
| } | |||
| ] | |||
| module.exports = Plugins | |||
| @@ -8,51 +8,51 @@ const fs = require('fs') | |||
| const Plugins = require('./DocsPlugins') | |||
| class Publish { | |||
| constructor() { | |||
| this.options = { | |||
| verbose: false | |||
| } | |||
| constructor() { | |||
| this.options = { | |||
| verbose: false | |||
| } | |||
| this.getArguments() | |||
| } | |||
| getArguments() { | |||
| if (process.argv.length > 2) { | |||
| const arg = process.argv[2] | |||
| switch (arg) { | |||
| case '-v': | |||
| case '--verbose': | |||
| this.options.verbose = true | |||
| break | |||
| default: | |||
| throw new Error(`Unknown option ${arg}`) | |||
| } | |||
| this.getArguments() | |||
| } | |||
| } | |||
| run() { | |||
| // Publish files | |||
| Plugins.forEach(module => { | |||
| try { | |||
| fse.copySync(module.from, module.to, { | |||
| // Skip copying dot files | |||
| filter(src) { | |||
| return !path.basename(src).startsWith('.') | |||
| } | |||
| }) | |||
| if (this.options.verbose) { | |||
| console.log(`Copied ${module.from} to ${module.to}`) | |||
| getArguments() { | |||
| if (process.argv.length > 2) { | |||
| const arg = process.argv[2] | |||
| switch (arg) { | |||
| case '-v': | |||
| case '--verbose': | |||
| this.options.verbose = true | |||
| break | |||
| default: | |||
| throw new Error(`Unknown option ${arg}`) | |||
| } | |||
| } | |||
| } catch (error) { | |||
| console.error(`Error: ${error}`) | |||
| } | |||
| }) | |||
| } | |||
| const insertText = '---\r\nlayout: page\r\ntitle: \r\n---\r\n' | |||
| run() { | |||
| // Publish files | |||
| Plugins.forEach(module => { | |||
| try { | |||
| fse.copySync(module.from, module.to, { | |||
| // Skip copying dot files | |||
| filter(src) { | |||
| return !path.basename(src).startsWith('.') | |||
| } | |||
| }) | |||
| if (this.options.verbose) { | |||
| console.log(`Copied ${module.from} to ${module.to}`) | |||
| } | |||
| } catch (error) { | |||
| console.error(`Error: ${error}`) | |||
| } | |||
| }) | |||
| const insertText = '---\r\nlayout: page\r\ntitle: \r\n---\r\n' | |||
| fs.writeFileSync('docs/how-to-contribute.md', insertText + fs.readFileSync('.github/CONTRIBUTING.md', 'utf8')) | |||
| } | |||
| fs.writeFileSync('docs/how-to-contribute.md', insertText + fs.readFileSync('.github/CONTRIBUTING.md', 'utf8')) | |||
| } | |||
| } | |||
| (new Publish()).run() | |||
| @@ -1,449 +1,449 @@ | |||
| 'use strict' | |||
| const Plugins = [ | |||
| // jQuery | |||
| { | |||
| from: 'node_modules/jquery/dist', | |||
| to: 'plugins/jquery' | |||
| }, | |||
| // Popper | |||
| { | |||
| from: 'node_modules/popper.js/dist', | |||
| to: 'plugins/popper' | |||
| }, | |||
| // Bootstrap | |||
| { | |||
| from: 'node_modules/bootstrap/dist/js', | |||
| to: 'plugins/bootstrap/js' | |||
| }, | |||
| // Font Awesome | |||
| { | |||
| from: 'node_modules/@fortawesome/fontawesome-free/css', | |||
| to: 'plugins/fontawesome-free/css' | |||
| }, | |||
| { | |||
| from: 'node_modules/@fortawesome/fontawesome-free/webfonts', | |||
| to: 'plugins/fontawesome-free/webfonts' | |||
| }, | |||
| // overlayScrollbars | |||
| { | |||
| from: 'node_modules/overlayscrollbars/js', | |||
| to: 'plugins/overlayScrollbars/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/overlayscrollbars/css', | |||
| to: 'plugins/overlayScrollbars/css' | |||
| }, | |||
| // Chart.js | |||
| { | |||
| from: 'node_modules/chart.js/dist/', | |||
| to: 'plugins/chart.js' | |||
| }, | |||
| // jQuery UI | |||
| { | |||
| from: 'node_modules/jquery-ui-dist/', | |||
| to: 'plugins/jquery-ui' | |||
| }, | |||
| // Flot | |||
| { | |||
| from: 'node_modules/flot/dist/es5/', | |||
| to: 'plugins/flot' | |||
| }, | |||
| { | |||
| from: 'node_modules/flot/source/', | |||
| to: 'plugins/flot/plugins' | |||
| }, | |||
| // Summernote | |||
| { | |||
| from: 'node_modules/summernote/dist/', | |||
| to: 'plugins/summernote' | |||
| }, | |||
| // Bootstrap Slider | |||
| { | |||
| from: 'node_modules/bootstrap-slider/dist/', | |||
| to: 'plugins/bootstrap-slider' | |||
| }, | |||
| { | |||
| from: 'node_modules/bootstrap-slider/dist/css', | |||
| to: 'plugins/bootstrap-slider/css' | |||
| }, | |||
| // Bootstrap Colorpicker | |||
| { | |||
| from: 'node_modules/bootstrap-colorpicker/dist/js', | |||
| to: 'plugins/bootstrap-colorpicker/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/bootstrap-colorpicker/dist/css', | |||
| to: 'plugins/bootstrap-colorpicker/css' | |||
| }, | |||
| // Tempusdominus Bootstrap 4 | |||
| { | |||
| from: 'node_modules/tempusdominus-bootstrap-4/build/js', | |||
| to: 'plugins/tempusdominus-bootstrap-4/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/tempusdominus-bootstrap-4/build/css', | |||
| to: 'plugins/tempusdominus-bootstrap-4/css' | |||
| }, | |||
| // Moment | |||
| { | |||
| from: 'node_modules/moment/min', | |||
| to: 'plugins/moment' | |||
| }, | |||
| { | |||
| from: 'node_modules/moment/locale', | |||
| to: 'plugins/moment/locale' | |||
| }, | |||
| // FastClick | |||
| { | |||
| from: 'node_modules/fastclick/lib', | |||
| to: 'plugins/fastclick' | |||
| }, | |||
| // Date Range Picker | |||
| { | |||
| from: 'node_modules/daterangepicker/', | |||
| to: 'plugins/daterangepicker' | |||
| }, | |||
| // DataTables | |||
| { | |||
| from: 'node_modules/pdfmake/build', | |||
| to: 'plugins/pdfmake' | |||
| }, | |||
| { | |||
| from: 'node_modules/jszip/dist', | |||
| to: 'plugins/jszip' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net/js', | |||
| to: 'plugins/datatables' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-bs4/js', | |||
| to: 'plugins/datatables-bs4/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-bs4/css', | |||
| to: 'plugins/datatables-bs4/css' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-autofill/js', | |||
| to: 'plugins/datatables-autofill/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-autofill-bs4/js', | |||
| to: 'plugins/datatables-autofill/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-autofill-bs4/css', | |||
| to: 'plugins/datatables-autofill/css' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-buttons/js', | |||
| to: 'plugins/datatables-buttons/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-buttons-bs4/js', | |||
| to: 'plugins/datatables-buttons/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-buttons-bs4/css', | |||
| to: 'plugins/datatables-buttons/css' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-colreorder/js', | |||
| to: 'plugins/datatables-colreorder/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-colreorder-bs4/js', | |||
| to: 'plugins/datatables-colreorder/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-colreorder-bs4/css', | |||
| to: 'plugins/datatables-colreorder/css' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-fixedcolumns/js', | |||
| to: 'plugins/datatables-fixedcolumns/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-fixedcolumns-bs4/js', | |||
| to: 'plugins/datatables-fixedcolumns/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-fixedcolumns-bs4/css', | |||
| to: 'plugins/datatables-fixedcolumns/css' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-fixedheader/js', | |||
| to: 'plugins/datatables-fixedheader/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-fixedheader-bs4/js', | |||
| to: 'plugins/datatables-fixedheader/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-fixedheader-bs4/css', | |||
| to: 'plugins/datatables-fixedheader/css' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-keytable/js', | |||
| to: 'plugins/datatables-keytable/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-keytable-bs4/js', | |||
| to: 'plugins/datatables-keytable/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-keytable-bs4/css', | |||
| to: 'plugins/datatables-keytable/css' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-responsive/js', | |||
| to: 'plugins/datatables-responsive/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-responsive-bs4/js', | |||
| to: 'plugins/datatables-responsive/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-responsive-bs4/css', | |||
| to: 'plugins/datatables-responsive/css' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-rowgroup/js', | |||
| to: 'plugins/datatables-rowgroup/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-rowgroup-bs4/js', | |||
| to: 'plugins/datatables-rowgroup/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-rowgroup-bs4/css', | |||
| to: 'plugins/datatables-rowgroup/css' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-rowreorder/js', | |||
| to: 'plugins/datatables-rowreorder/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-rowreorder-bs4/js', | |||
| to: 'plugins/datatables-rowreorder/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-rowreorder-bs4/css', | |||
| to: 'plugins/datatables-rowreorder/css' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-scroller/js', | |||
| to: 'plugins/datatables-scroller/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-scroller-bs4/js', | |||
| to: 'plugins/datatables-scroller/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-scroller-bs4/css', | |||
| to: 'plugins/datatables-scroller/css' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-searchbuilder/js', | |||
| to: 'plugins/datatables-searchbuilder/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-searchbuilder-bs4/js', | |||
| to: 'plugins/datatables-searchbuilder/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-searchbuilder-bs4/css', | |||
| to: 'plugins/datatables-searchbuilder/css' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-searchpanes/js', | |||
| to: 'plugins/datatables-searchpanes/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-searchpanes-bs4/js', | |||
| to: 'plugins/datatables-searchpanes/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-searchpanes-bs4/css', | |||
| to: 'plugins/datatables-searchpanes/css' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-select/js', | |||
| to: 'plugins/datatables-select/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-select-bs4/js', | |||
| to: 'plugins/datatables-select/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-select-bs4/css', | |||
| to: 'plugins/datatables-select/css' | |||
| }, | |||
| // jQuery | |||
| { | |||
| from: 'node_modules/jquery/dist', | |||
| to: 'plugins/jquery' | |||
| }, | |||
| // Popper | |||
| { | |||
| from: 'node_modules/popper.js/dist', | |||
| to: 'plugins/popper' | |||
| }, | |||
| // Bootstrap | |||
| { | |||
| from: 'node_modules/bootstrap/dist/js', | |||
| to: 'plugins/bootstrap/js' | |||
| }, | |||
| // Font Awesome | |||
| { | |||
| from: 'node_modules/@fortawesome/fontawesome-free/css', | |||
| to: 'plugins/fontawesome-free/css' | |||
| }, | |||
| { | |||
| from: 'node_modules/@fortawesome/fontawesome-free/webfonts', | |||
| to: 'plugins/fontawesome-free/webfonts' | |||
| }, | |||
| // overlayScrollbars | |||
| { | |||
| from: 'node_modules/overlayscrollbars/js', | |||
| to: 'plugins/overlayScrollbars/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/overlayscrollbars/css', | |||
| to: 'plugins/overlayScrollbars/css' | |||
| }, | |||
| // Chart.js | |||
| { | |||
| from: 'node_modules/chart.js/dist/', | |||
| to: 'plugins/chart.js' | |||
| }, | |||
| // jQuery UI | |||
| { | |||
| from: 'node_modules/jquery-ui-dist/', | |||
| to: 'plugins/jquery-ui' | |||
| }, | |||
| // Flot | |||
| { | |||
| from: 'node_modules/flot/dist/es5/', | |||
| to: 'plugins/flot' | |||
| }, | |||
| { | |||
| from: 'node_modules/flot/source/', | |||
| to: 'plugins/flot/plugins' | |||
| }, | |||
| // Summernote | |||
| { | |||
| from: 'node_modules/summernote/dist/', | |||
| to: 'plugins/summernote' | |||
| }, | |||
| // Bootstrap Slider | |||
| { | |||
| from: 'node_modules/bootstrap-slider/dist/', | |||
| to: 'plugins/bootstrap-slider' | |||
| }, | |||
| { | |||
| from: 'node_modules/bootstrap-slider/dist/css', | |||
| to: 'plugins/bootstrap-slider/css' | |||
| }, | |||
| // Bootstrap Colorpicker | |||
| { | |||
| from: 'node_modules/bootstrap-colorpicker/dist/js', | |||
| to: 'plugins/bootstrap-colorpicker/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/bootstrap-colorpicker/dist/css', | |||
| to: 'plugins/bootstrap-colorpicker/css' | |||
| }, | |||
| // Tempusdominus Bootstrap 4 | |||
| { | |||
| from: 'node_modules/tempusdominus-bootstrap-4/build/js', | |||
| to: 'plugins/tempusdominus-bootstrap-4/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/tempusdominus-bootstrap-4/build/css', | |||
| to: 'plugins/tempusdominus-bootstrap-4/css' | |||
| }, | |||
| // Moment | |||
| { | |||
| from: 'node_modules/moment/min', | |||
| to: 'plugins/moment' | |||
| }, | |||
| { | |||
| from: 'node_modules/moment/locale', | |||
| to: 'plugins/moment/locale' | |||
| }, | |||
| // FastClick | |||
| { | |||
| from: 'node_modules/fastclick/lib', | |||
| to: 'plugins/fastclick' | |||
| }, | |||
| // Date Range Picker | |||
| { | |||
| from: 'node_modules/daterangepicker/', | |||
| to: 'plugins/daterangepicker' | |||
| }, | |||
| // DataTables | |||
| { | |||
| from: 'node_modules/pdfmake/build', | |||
| to: 'plugins/pdfmake' | |||
| }, | |||
| { | |||
| from: 'node_modules/jszip/dist', | |||
| to: 'plugins/jszip' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net/js', | |||
| to: 'plugins/datatables' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-bs4/js', | |||
| to: 'plugins/datatables-bs4/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-bs4/css', | |||
| to: 'plugins/datatables-bs4/css' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-autofill/js', | |||
| to: 'plugins/datatables-autofill/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-autofill-bs4/js', | |||
| to: 'plugins/datatables-autofill/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-autofill-bs4/css', | |||
| to: 'plugins/datatables-autofill/css' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-buttons/js', | |||
| to: 'plugins/datatables-buttons/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-buttons-bs4/js', | |||
| to: 'plugins/datatables-buttons/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-buttons-bs4/css', | |||
| to: 'plugins/datatables-buttons/css' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-colreorder/js', | |||
| to: 'plugins/datatables-colreorder/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-colreorder-bs4/js', | |||
| to: 'plugins/datatables-colreorder/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-colreorder-bs4/css', | |||
| to: 'plugins/datatables-colreorder/css' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-fixedcolumns/js', | |||
| to: 'plugins/datatables-fixedcolumns/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-fixedcolumns-bs4/js', | |||
| to: 'plugins/datatables-fixedcolumns/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-fixedcolumns-bs4/css', | |||
| to: 'plugins/datatables-fixedcolumns/css' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-fixedheader/js', | |||
| to: 'plugins/datatables-fixedheader/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-fixedheader-bs4/js', | |||
| to: 'plugins/datatables-fixedheader/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-fixedheader-bs4/css', | |||
| to: 'plugins/datatables-fixedheader/css' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-keytable/js', | |||
| to: 'plugins/datatables-keytable/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-keytable-bs4/js', | |||
| to: 'plugins/datatables-keytable/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-keytable-bs4/css', | |||
| to: 'plugins/datatables-keytable/css' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-responsive/js', | |||
| to: 'plugins/datatables-responsive/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-responsive-bs4/js', | |||
| to: 'plugins/datatables-responsive/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-responsive-bs4/css', | |||
| to: 'plugins/datatables-responsive/css' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-rowgroup/js', | |||
| to: 'plugins/datatables-rowgroup/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-rowgroup-bs4/js', | |||
| to: 'plugins/datatables-rowgroup/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-rowgroup-bs4/css', | |||
| to: 'plugins/datatables-rowgroup/css' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-rowreorder/js', | |||
| to: 'plugins/datatables-rowreorder/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-rowreorder-bs4/js', | |||
| to: 'plugins/datatables-rowreorder/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-rowreorder-bs4/css', | |||
| to: 'plugins/datatables-rowreorder/css' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-scroller/js', | |||
| to: 'plugins/datatables-scroller/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-scroller-bs4/js', | |||
| to: 'plugins/datatables-scroller/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-scroller-bs4/css', | |||
| to: 'plugins/datatables-scroller/css' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-searchbuilder/js', | |||
| to: 'plugins/datatables-searchbuilder/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-searchbuilder-bs4/js', | |||
| to: 'plugins/datatables-searchbuilder/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-searchbuilder-bs4/css', | |||
| to: 'plugins/datatables-searchbuilder/css' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-searchpanes/js', | |||
| to: 'plugins/datatables-searchpanes/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-searchpanes-bs4/js', | |||
| to: 'plugins/datatables-searchpanes/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-searchpanes-bs4/css', | |||
| to: 'plugins/datatables-searchpanes/css' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-select/js', | |||
| to: 'plugins/datatables-select/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-select-bs4/js', | |||
| to: 'plugins/datatables-select/js' | |||
| }, | |||
| { | |||
| from: 'node_modules/datatables.net-select-bs4/css', | |||
| to: 'plugins/datatables-select/css' | |||
| }, | |||
| // Fullcalendar | |||
| { | |||
| from: 'node_modules/fullcalendar/', | |||
| to: 'plugins/fullcalendar' | |||
| }, | |||
| // icheck bootstrap | |||
| { | |||
| from: 'node_modules/icheck-bootstrap/', | |||
| to: 'plugins/icheck-bootstrap' | |||
| }, | |||
| // inputmask | |||
| { | |||
| from: 'node_modules/inputmask/dist/', | |||
| to: 'plugins/inputmask' | |||
| }, | |||
| // ion-rangeslider | |||
| { | |||
| from: 'node_modules/ion-rangeslider/', | |||
| to: 'plugins/ion-rangeslider' | |||
| }, | |||
| // JQVMap (jqvmap-novulnerability) | |||
| { | |||
| from: 'node_modules/jqvmap-novulnerability/dist/', | |||
| to: 'plugins/jqvmap' | |||
| }, | |||
| // jQuery Mapael | |||
| { | |||
| from: 'node_modules/jquery-mapael/js/', | |||
| to: 'plugins/jquery-mapael' | |||
| }, | |||
| // Raphael | |||
| { | |||
| from: 'node_modules/raphael/', | |||
| to: 'plugins/raphael' | |||
| }, | |||
| // jQuery Mousewheel | |||
| { | |||
| from: 'node_modules/jquery-mousewheel/', | |||
| to: 'plugins/jquery-mousewheel' | |||
| }, | |||
| // jQuery Knob | |||
| { | |||
| from: 'node_modules/jquery-knob-chif/dist/', | |||
| to: 'plugins/jquery-knob' | |||
| }, | |||
| // pace-progress | |||
| { | |||
| from: 'node_modules/@lgaitan/pace-progress/dist/', | |||
| to: 'plugins/pace-progress' | |||
| }, | |||
| // Select2 | |||
| { | |||
| from: 'node_modules/select2/dist/', | |||
| to: 'plugins/select2' | |||
| }, | |||
| { | |||
| from: 'node_modules/@ttskch/select2-bootstrap4-theme/dist/', | |||
| to: 'plugins/select2-bootstrap4-theme' | |||
| }, | |||
| // Sparklines | |||
| { | |||
| from: 'node_modules/sparklines/source/', | |||
| to: 'plugins/sparklines' | |||
| }, | |||
| // SweetAlert2 | |||
| { | |||
| from: 'node_modules/sweetalert2/dist/', | |||
| to: 'plugins/sweetalert2' | |||
| }, | |||
| { | |||
| from: 'node_modules/@sweetalert2/theme-bootstrap-4/', | |||
| to: 'plugins/sweetalert2-theme-bootstrap-4' | |||
| }, | |||
| // Toastr | |||
| { | |||
| from: 'node_modules/toastr/build/', | |||
| to: 'plugins/toastr' | |||
| }, | |||
| // jsGrid | |||
| { | |||
| from: 'node_modules/jsgrid/dist', | |||
| to: 'plugins/jsgrid' | |||
| }, | |||
| { | |||
| from: 'node_modules/jsgrid/demos/db.js', | |||
| to: 'plugins/jsgrid/demos/db.js' | |||
| }, | |||
| // flag-icon-css | |||
| { | |||
| from: 'node_modules/flag-icon-css/css', | |||
| to: 'plugins/flag-icon-css/css' | |||
| }, | |||
| { | |||
| from: 'node_modules/flag-icon-css/flags', | |||
| to: 'plugins/flag-icon-css/flags' | |||
| }, | |||
| // bootstrap4-duallistbox | |||
| { | |||
| from: 'node_modules/bootstrap4-duallistbox/dist', | |||
| to: 'plugins/bootstrap4-duallistbox/' | |||
| }, | |||
| // filterizr | |||
| { | |||
| from: 'node_modules/filterizr/dist', | |||
| to: 'plugins/filterizr/' | |||
| }, | |||
| // ekko-lightbox | |||
| { | |||
| from: 'node_modules/ekko-lightbox/dist', | |||
| to: 'plugins/ekko-lightbox/' | |||
| }, | |||
| // bootstrap-switch | |||
| { | |||
| from: 'node_modules/bootstrap-switch/dist', | |||
| to: 'plugins/bootstrap-switch/' | |||
| }, | |||
| // jQuery Validate | |||
| { | |||
| from: 'node_modules/jquery-validation/dist/', | |||
| to: 'plugins/jquery-validation' | |||
| }, | |||
| // bs-custom-file-input | |||
| { | |||
| from: 'node_modules/bs-custom-file-input/dist/', | |||
| to: 'plugins/bs-custom-file-input' | |||
| }, | |||
| // bs-stepper | |||
| { | |||
| from: 'node_modules/bs-stepper/dist/', | |||
| to: 'plugins/bs-stepper' | |||
| }, | |||
| // CodeMirror | |||
| { | |||
| from: 'node_modules/codemirror/lib/', | |||
| to: 'plugins/codemirror' | |||
| }, | |||
| { | |||
| from: 'node_modules/codemirror/addon/', | |||
| to: 'plugins/codemirror/addon' | |||
| }, | |||
| { | |||
| from: 'node_modules/codemirror/keymap/', | |||
| to: 'plugins/codemirror/keymap' | |||
| }, | |||
| { | |||
| from: 'node_modules/codemirror/mode/', | |||
| to: 'plugins/codemirror/mode' | |||
| }, | |||
| { | |||
| from: 'node_modules/codemirror/theme/', | |||
| to: 'plugins/codemirror/theme' | |||
| }, | |||
| // dropzonejs | |||
| { | |||
| from: 'node_modules/dropzone/dist/', | |||
| to: 'plugins/dropzone' | |||
| }, | |||
| // uPlot | |||
| { | |||
| from: 'node_modules/uplot/dist/', | |||
| to: 'plugins/uplot' | |||
| } | |||
| // Fullcalendar | |||
| { | |||
| from: 'node_modules/fullcalendar/', | |||
| to: 'plugins/fullcalendar' | |||
| }, | |||
| // icheck bootstrap | |||
| { | |||
| from: 'node_modules/icheck-bootstrap/', | |||
| to: 'plugins/icheck-bootstrap' | |||
| }, | |||
| // inputmask | |||
| { | |||
| from: 'node_modules/inputmask/dist/', | |||
| to: 'plugins/inputmask' | |||
| }, | |||
| // ion-rangeslider | |||
| { | |||
| from: 'node_modules/ion-rangeslider/', | |||
| to: 'plugins/ion-rangeslider' | |||
| }, | |||
| // JQVMap (jqvmap-novulnerability) | |||
| { | |||
| from: 'node_modules/jqvmap-novulnerability/dist/', | |||
| to: 'plugins/jqvmap' | |||
| }, | |||
| // jQuery Mapael | |||
| { | |||
| from: 'node_modules/jquery-mapael/js/', | |||
| to: 'plugins/jquery-mapael' | |||
| }, | |||
| // Raphael | |||
| { | |||
| from: 'node_modules/raphael/', | |||
| to: 'plugins/raphael' | |||
| }, | |||
| // jQuery Mousewheel | |||
| { | |||
| from: 'node_modules/jquery-mousewheel/', | |||
| to: 'plugins/jquery-mousewheel' | |||
| }, | |||
| // jQuery Knob | |||
| { | |||
| from: 'node_modules/jquery-knob-chif/dist/', | |||
| to: 'plugins/jquery-knob' | |||
| }, | |||
| // pace-progress | |||
| { | |||
| from: 'node_modules/@lgaitan/pace-progress/dist/', | |||
| to: 'plugins/pace-progress' | |||
| }, | |||
| // Select2 | |||
| { | |||
| from: 'node_modules/select2/dist/', | |||
| to: 'plugins/select2' | |||
| }, | |||
| { | |||
| from: 'node_modules/@ttskch/select2-bootstrap4-theme/dist/', | |||
| to: 'plugins/select2-bootstrap4-theme' | |||
| }, | |||
| // Sparklines | |||
| { | |||
| from: 'node_modules/sparklines/source/', | |||
| to: 'plugins/sparklines' | |||
| }, | |||
| // SweetAlert2 | |||
| { | |||
| from: 'node_modules/sweetalert2/dist/', | |||
| to: 'plugins/sweetalert2' | |||
| }, | |||
| { | |||
| from: 'node_modules/@sweetalert2/theme-bootstrap-4/', | |||
| to: 'plugins/sweetalert2-theme-bootstrap-4' | |||
| }, | |||
| // Toastr | |||
| { | |||
| from: 'node_modules/toastr/build/', | |||
| to: 'plugins/toastr' | |||
| }, | |||
| // jsGrid | |||
| { | |||
| from: 'node_modules/jsgrid/dist', | |||
| to: 'plugins/jsgrid' | |||
| }, | |||
| { | |||
| from: 'node_modules/jsgrid/demos/db.js', | |||
| to: 'plugins/jsgrid/demos/db.js' | |||
| }, | |||
| // flag-icon-css | |||
| { | |||
| from: 'node_modules/flag-icon-css/css', | |||
| to: 'plugins/flag-icon-css/css' | |||
| }, | |||
| { | |||
| from: 'node_modules/flag-icon-css/flags', | |||
| to: 'plugins/flag-icon-css/flags' | |||
| }, | |||
| // bootstrap4-duallistbox | |||
| { | |||
| from: 'node_modules/bootstrap4-duallistbox/dist', | |||
| to: 'plugins/bootstrap4-duallistbox/' | |||
| }, | |||
| // filterizr | |||
| { | |||
| from: 'node_modules/filterizr/dist', | |||
| to: 'plugins/filterizr/' | |||
| }, | |||
| // ekko-lightbox | |||
| { | |||
| from: 'node_modules/ekko-lightbox/dist', | |||
| to: 'plugins/ekko-lightbox/' | |||
| }, | |||
| // bootstrap-switch | |||
| { | |||
| from: 'node_modules/bootstrap-switch/dist', | |||
| to: 'plugins/bootstrap-switch/' | |||
| }, | |||
| // jQuery Validate | |||
| { | |||
| from: 'node_modules/jquery-validation/dist/', | |||
| to: 'plugins/jquery-validation' | |||
| }, | |||
| // bs-custom-file-input | |||
| { | |||
| from: 'node_modules/bs-custom-file-input/dist/', | |||
| to: 'plugins/bs-custom-file-input' | |||
| }, | |||
| // bs-stepper | |||
| { | |||
| from: 'node_modules/bs-stepper/dist/', | |||
| to: 'plugins/bs-stepper' | |||
| }, | |||
| // CodeMirror | |||
| { | |||
| from: 'node_modules/codemirror/lib/', | |||
| to: 'plugins/codemirror' | |||
| }, | |||
| { | |||
| from: 'node_modules/codemirror/addon/', | |||
| to: 'plugins/codemirror/addon' | |||
| }, | |||
| { | |||
| from: 'node_modules/codemirror/keymap/', | |||
| to: 'plugins/codemirror/keymap' | |||
| }, | |||
| { | |||
| from: 'node_modules/codemirror/mode/', | |||
| to: 'plugins/codemirror/mode' | |||
| }, | |||
| { | |||
| from: 'node_modules/codemirror/theme/', | |||
| to: 'plugins/codemirror/theme' | |||
| }, | |||
| // dropzonejs | |||
| { | |||
| from: 'node_modules/dropzone/dist/', | |||
| to: 'plugins/dropzone' | |||
| }, | |||
| // uPlot | |||
| { | |||
| from: 'node_modules/uplot/dist/', | |||
| to: 'plugins/uplot' | |||
| } | |||
| ] | |||
| module.exports = Plugins | |||
| @@ -7,53 +7,53 @@ const fse = require('fs-extra') | |||
| const Plugins = require('./Plugins') | |||
| class Publish { | |||
| constructor() { | |||
| this.options = { | |||
| verbose: false | |||
| } | |||
| constructor() { | |||
| this.options = { | |||
| verbose: false | |||
| } | |||
| this.getArguments() | |||
| } | |||
| getArguments() { | |||
| if (process.argv.length > 2) { | |||
| const arg = process.argv[2] | |||
| switch (arg) { | |||
| case '-v': | |||
| case '--verbose': | |||
| this.options.verbose = true | |||
| break | |||
| default: | |||
| throw new Error(`Unknown option ${arg}`) | |||
| } | |||
| this.getArguments() | |||
| } | |||
| } | |||
| run() { | |||
| // Publish files | |||
| Plugins.forEach(module => { | |||
| const fseOptions = { | |||
| // Skip copying dot files | |||
| filter(src) { | |||
| return !path.basename(src).startsWith('.') | |||
| } | |||
| } | |||
| try { | |||
| if (fse.existsSync(module.from)) { | |||
| fse.copySync(module.from, module.to, fseOptions) | |||
| } else { | |||
| fse.copySync(module.from.replace('node_modules/', '../'), module.to, fseOptions) | |||
| getArguments() { | |||
| if (process.argv.length > 2) { | |||
| const arg = process.argv[2] | |||
| switch (arg) { | |||
| case '-v': | |||
| case '--verbose': | |||
| this.options.verbose = true | |||
| break | |||
| default: | |||
| throw new Error(`Unknown option ${arg}`) | |||
| } | |||
| } | |||
| } | |||
| if (this.options.verbose) { | |||
| console.log(`Copied ${module.from} to ${module.to}`) | |||
| } | |||
| } catch (error) { | |||
| console.error(`Error: ${error}`) | |||
| } | |||
| }) | |||
| } | |||
| run() { | |||
| // Publish files | |||
| Plugins.forEach(module => { | |||
| const fseOptions = { | |||
| // Skip copying dot files | |||
| filter(src) { | |||
| return !path.basename(src).startsWith('.') | |||
| } | |||
| } | |||
| try { | |||
| if (fse.existsSync(module.from)) { | |||
| fse.copySync(module.from, module.to, fseOptions) | |||
| } else { | |||
| fse.copySync(module.from.replace('node_modules/', '../'), module.to, fseOptions) | |||
| } | |||
| if (this.options.verbose) { | |||
| console.log(`Copied ${module.from} to ${module.to}`) | |||
| } | |||
| } catch (error) { | |||
| console.error(`Error: ${error}`) | |||
| } | |||
| }) | |||
| } | |||
| } | |||
| (new Publish()).run() | |||
| @@ -13,43 +13,43 @@ const childProcess = require('child_process') | |||
| const vnu = require('vnu-jar') | |||
| childProcess.exec('java -version', (error, stdout, stderr) => { | |||
| if (error) { | |||
| console.error('Skipping vnu-jar test; Java is missing.') | |||
| return | |||
| } | |||
| const is32bitJava = !/64-Bit/.test(stderr) | |||
| // vnu-jar accepts multiple ignores joined with a `|`. | |||
| // Also note that the ignores are regular expressions. | |||
| const ignores = [ | |||
| // "autocomplete" is included in <button> and checkboxes and radio <input>s due to | |||
| // Firefox's non-standard autocomplete behavior - see https://bugzilla.mozilla.org/show_bug.cgi?id=654072 | |||
| 'Attribute “autocomplete” is only allowed when the input type is.*' | |||
| ].join('|') | |||
| const args = [ | |||
| '-jar', | |||
| vnu, | |||
| '--asciiquotes', | |||
| '--skip-non-html', | |||
| // Ignore the language code warnings | |||
| '--no-langdetect', | |||
| '--Werror', | |||
| `--filterpattern "${ignores}"`, | |||
| './*.html', | |||
| 'docs_html/', | |||
| 'pages/' | |||
| ] | |||
| // For the 32-bit Java we need to pass `-Xss512k` | |||
| if (is32bitJava) { | |||
| args.splice(0, 0, '-Xss512k') | |||
| } | |||
| return childProcess.spawn('java', args, { | |||
| shell: true, | |||
| stdio: 'inherit' | |||
| }) | |||
| .on('exit', process.exit) | |||
| if (error) { | |||
| console.error('Skipping vnu-jar test; Java is missing.') | |||
| return | |||
| } | |||
| const is32bitJava = !/64-Bit/.test(stderr) | |||
| // vnu-jar accepts multiple ignores joined with a `|`. | |||
| // Also note that the ignores are regular expressions. | |||
| const ignores = [ | |||
| // "autocomplete" is included in <button> and checkboxes and radio <input>s due to | |||
| // Firefox's non-standard autocomplete behavior - see https://bugzilla.mozilla.org/show_bug.cgi?id=654072 | |||
| 'Attribute “autocomplete” is only allowed when the input type is.*' | |||
| ].join('|') | |||
| const args = [ | |||
| '-jar', | |||
| vnu, | |||
| '--asciiquotes', | |||
| '--skip-non-html', | |||
| // Ignore the language code warnings | |||
| '--no-langdetect', | |||
| '--Werror', | |||
| `--filterpattern "${ignores}"`, | |||
| './*.html', | |||
| 'docs_html/', | |||
| 'pages/' | |||
| ] | |||
| // For the 32-bit Java we need to pass `-Xss512k` | |||
| if (is32bitJava) { | |||
| args.splice(0, 0, '-Xss512k') | |||
| } | |||
| return childProcess.spawn('java', args, { | |||
| shell: true, | |||
| stdio: 'inherit' | |||
| }) | |||
| .on('exit', process.exit) | |||
| }) | |||
| @@ -6,6 +6,7 @@ | |||
| &__shake { | |||
| animation: shake 1500ms; | |||
| } | |||
| &__wobble { | |||
| animation: wobble 1500ms; | |||
| } | |||
| @@ -127,6 +127,7 @@ | |||
| border-color: lighten($gray-600, 2.5%); | |||
| } | |||
| } | |||
| .btn-light { | |||
| background-color: lighten($dark, 7.5%); | |||
| color: $white; | |||
| @@ -206,7 +206,7 @@ html.maximized-card { | |||
| .card-header, | |||
| .card-body, | |||
| .card-footer { | |||
| @include clearfix (); | |||
| @include clearfix(); | |||
| } | |||
| // Box header | |||
| @@ -314,7 +314,7 @@ html.maximized-card { | |||
| } | |||
| .chart-legend { | |||
| @include list-unstyled (); | |||
| @include list-unstyled(); | |||
| margin: 10px 0; | |||
| > li { | |||
| @@ -330,7 +330,7 @@ html.maximized-card { | |||
| background-color: $gray-100; | |||
| .card-comment { | |||
| @include clearfix (); | |||
| @include clearfix(); | |||
| border-bottom: 1px solid $gray-200; | |||
| padding: 8px 0; | |||
| @@ -498,16 +498,20 @@ html.maximized-card { | |||
| background-color: lighten($dark, 5%); | |||
| color: $white; | |||
| } | |||
| .nav.flex-column > li { | |||
| border-bottom-color: $gray-600; | |||
| } | |||
| .card-footer { | |||
| background-color: rgba($black, .1); | |||
| } | |||
| &.card-outline-tabs .card-header a:hover { | |||
| border-color: $gray-600; | |||
| border-bottom-color: transparent; | |||
| } | |||
| &:not(.card-outline) > .card-header a.active { | |||
| color: $white; | |||
| } | |||
| @@ -515,9 +519,11 @@ html.maximized-card { | |||
| .card-comments { | |||
| background-color: lighten($dark, 1.25%); | |||
| .username { | |||
| color: $gray-400; | |||
| } | |||
| .card-comment { | |||
| border-bottom-color: lighten($dark, 7.5%); | |||
| } | |||
| @@ -6,6 +6,7 @@ | |||
| .carousel-control-prev & { | |||
| margin-left: -20px; | |||
| } | |||
| .carousel-control-next & { | |||
| margin-right: 20px; | |||
| } | |||
| @@ -95,6 +95,7 @@ a.text-muted:hover { | |||
| background-color: lighten($dark, 7.5%) !important; | |||
| color: $white !important; | |||
| } | |||
| .text-black, | |||
| .text-dark, | |||
| .link-black, | |||
| @@ -42,7 +42,7 @@ | |||
| } | |||
| .direct-chat-msg { | |||
| @include clearfix (); | |||
| @include clearfix(); | |||
| margin-bottom: 10px; | |||
| } | |||
| @@ -163,10 +163,10 @@ | |||
| //Contacts list -- for displaying contacts in direct chat contacts pane | |||
| .contacts-list { | |||
| @include list-unstyled (); | |||
| @include list-unstyled(); | |||
| > li { | |||
| @include clearfix (); | |||
| @include clearfix(); | |||
| border-bottom: 1px solid rgba($black, .2); | |||
| margin: 0; | |||
| padding: 10px; | |||
| @@ -234,9 +234,11 @@ | |||
| border-right-color: lighten($dark, 10%); | |||
| } | |||
| } | |||
| .direct-chat-timestamp { | |||
| color: $gray-500; | |||
| } | |||
| .right > .direct-chat-text { | |||
| &::after, | |||
| &::before { | |||
| @@ -58,7 +58,7 @@ | |||
| position: relative; | |||
| > a::after { | |||
| @include caret-right (); | |||
| @include caret-right(); | |||
| float: right; | |||
| margin-left: .5rem; | |||
| margin-top: .5rem; | |||
| @@ -125,6 +125,7 @@ | |||
| .navbar-custom-menu > .navbar-nav { | |||
| > li { | |||
| position: relative; | |||
| > .dropdown-menu { | |||
| position: absolute; | |||
| right: 0; | |||
| @@ -136,8 +137,10 @@ | |||
| @include media-breakpoint-down(sm) { | |||
| .navbar-custom-menu > .navbar-nav { | |||
| float: right; | |||
| > li { | |||
| position: static; | |||
| > .dropdown-menu { | |||
| position: absolute; | |||
| right: 5%; | |||
| @@ -196,7 +199,7 @@ | |||
| // Menu Body | |||
| > .user-body { | |||
| @include clearfix (); | |||
| @include clearfix(); | |||
| border-bottom: 1px solid $gray-700; | |||
| border-top: 1px solid $gray-300; | |||
| padding: 15px; | |||
| @@ -211,7 +214,7 @@ | |||
| // Menu Footer | |||
| > .user-footer { | |||
| @include clearfix (); | |||
| @include clearfix(); | |||
| background-color: $gray-100; | |||
| padding: 10px; | |||
| @@ -249,6 +252,7 @@ | |||
| background-color: $dark; | |||
| color: $white; | |||
| } | |||
| .dropdown-item { | |||
| color: $white; | |||
| @@ -257,6 +261,7 @@ | |||
| background-color: lighten($dark, 5%); | |||
| } | |||
| } | |||
| .dropdown-divider { | |||
| border-color: $gray-600; | |||
| } | |||
| @@ -274,14 +279,17 @@ | |||
| background-color: lighten($dark, 5%); | |||
| color: $gray-300; | |||
| } | |||
| &:focus { | |||
| background-color: lighten($dark, 7.5%); | |||
| } | |||
| } | |||
| } | |||
| > .user-body { | |||
| border-color: $gray-600; | |||
| } | |||
| > .user-body a { | |||
| background-color: transparent !important; | |||
| color: $white !important; | |||
| @@ -284,6 +284,7 @@ body.text-sm { | |||
| &.border-width-2 { | |||
| border-bottom-width: 2px; | |||
| } | |||
| &.border-width-3 { | |||
| border-bottom-width: 3px; | |||
| } | |||
| @@ -326,6 +327,7 @@ body.text-sm { | |||
| background-color: transparent !important; | |||
| box-shadow: none; | |||
| } | |||
| &:checked ~ .custom-control-label::before { | |||
| @include gradient-bg(transparent); | |||
| } | |||
| @@ -338,10 +340,12 @@ body.text-sm { | |||
| border: 1px solid lighten($sidebar-dark-bg, 15%); | |||
| color: lighten(color-yiq(lighten($sidebar-dark-bg, 5%)), 15%); | |||
| } | |||
| .btn-navbar { | |||
| &:hover { | |||
| background-color: lighten($sidebar-dark-bg, 7.5%); | |||
| } | |||
| &:focus { | |||
| background-color: lighten($sidebar-dark-bg, 10%); | |||
| } | |||
| @@ -368,11 +372,13 @@ body.text-sm { | |||
| background-color: $dark; | |||
| color: $white; | |||
| } | |||
| .form-control:not(.form-control-navbar):not(.form-control-sidebar):not(.is-invalid):not(:focus), | |||
| .custom-file-label, | |||
| .custom-file-label::after { | |||
| border-color: $gray-600; | |||
| } | |||
| select { | |||
| background-color: $dark; | |||
| color: $white; | |||
| @@ -394,9 +400,11 @@ body.text-sm { | |||
| &::-webkit-slider-runnable-track { | |||
| background-color: lighten($dark, 7.5%); | |||
| } | |||
| &::-moz-range-track { | |||
| background-color: lighten($dark, 7.5%); | |||
| } | |||
| &::-ms-track { | |||
| background-color: lighten($dark, 7.5%); | |||
| } | |||
| @@ -689,10 +689,12 @@ body:not(.layout-fixed) { | |||
| color: $gray-500; | |||
| } | |||
| } | |||
| .main-footer { | |||
| background-color: $dark; | |||
| border-color: lighten($dark, 10%); | |||
| } | |||
| .content-wrapper { | |||
| background-color: lighten($dark, 7.5%); | |||
| color: $white; | |||
| @@ -390,7 +390,7 @@ | |||
| // Hover and active states | |||
| &.menu-open > .nav-link, | |||
| &:hover > .nav-link, | |||
| > .nav-link:focus { | |||
| > .nav-link:focus { | |||
| background-color: $sidebar-dark-hover-bg; | |||
| color: $sidebar-dark-hover-color; | |||
| } | |||
| @@ -767,7 +767,7 @@ | |||
| } | |||
| &.active { | |||
| > .nav-icon{ | |||
| > .nav-icon { | |||
| margin-left: .36rem; | |||
| } | |||
| } | |||
| @@ -793,7 +793,7 @@ | |||
| } | |||
| &.active { | |||
| > .nav-icon{ | |||
| > .nav-icon { | |||
| margin-left: calc(.75rem - 3px); | |||
| } | |||
| } | |||
| @@ -988,6 +988,7 @@ | |||
| width: 100%; | |||
| flex-wrap: nowrap; | |||
| } | |||
| .sidebar nav .form-inline { | |||
| margin-bottom: .2rem; | |||
| } | |||
| @@ -997,6 +998,7 @@ | |||
| &.sidebar-collapse .main-sidebar { | |||
| margin-left: 0; | |||
| } | |||
| .content-wrapper, | |||
| .main-header, | |||
| .main-footer { | |||
| @@ -296,6 +296,7 @@ | |||
| // Box overlay for LOADING STATE effect on Tab Panels | |||
| > .overlay-wrapper { | |||
| position: relative; | |||
| > .overlay { | |||
| border-top-left-radius: 0; | |||
| border-top-right-radius: 0; | |||
| @@ -486,6 +487,7 @@ blockquote { | |||
| a:not(.btn):hover { | |||
| color: lighten($link-color, 10%); | |||
| } | |||
| .attachment-block { | |||
| background-color: lighten($dark, 3.75%); | |||
| @@ -493,6 +495,7 @@ blockquote { | |||
| color: $gray-400; | |||
| } | |||
| } | |||
| blockquote { | |||
| background-color: lighten($dark, 5%); | |||
| @@ -526,14 +529,17 @@ blockquote { | |||
| } | |||
| } | |||
| } | |||
| .close, | |||
| .mailbox-attachment-close { | |||
| color: $gray-500; | |||
| text-shadow: 0 1px 0 $gray-700; | |||
| } | |||
| .tab-custom-content { | |||
| border-color: $gray-600; | |||
| } | |||
| .list-group-item { | |||
| background-color: $dark; | |||
| border-color: $gray-600; | |||
| @@ -48,6 +48,7 @@ | |||
| .modal-footer { | |||
| border-color: $gray-600; | |||
| } | |||
| .modal-content { | |||
| background-color: $dark; | |||
| @@ -56,6 +57,7 @@ | |||
| .modal-footer { | |||
| border-color: $gray-600; | |||
| } | |||
| .close { | |||
| color: $dark !important; | |||
| text-shadow: 0 1px 0 $gray-700 !important; | |||
| @@ -30,7 +30,7 @@ | |||
| border-top-right-radius: 0; | |||
| margin-right: -$nav-tabs-border-width; | |||
| @include hover-focus () { | |||
| @include hover-focus() { | |||
| border-color: $gray-200 transparent $gray-200 $gray-200; | |||
| } | |||
| } | |||
| @@ -51,7 +51,7 @@ | |||
| border-top-right-radius: $nav-tabs-border-radius; | |||
| margin-left: -$nav-tabs-border-width; | |||
| @include hover-focus () { | |||
| @include hover-focus() { | |||
| border-color: $gray-200 $gray-200 $gray-200 transparent; | |||
| } | |||
| } | |||
| @@ -126,13 +126,16 @@ | |||
| &:hover { | |||
| border-color: lighten($dark, 15%) transparent lighten($dark, 15%) lighten($dark, 15%); | |||
| } | |||
| &:focus, | |||
| &:hover { | |||
| background-color: lighten($dark, 5%); | |||
| } | |||
| } | |||
| &.nav-tabs-right { | |||
| border-color: lighten($dark, 15%); | |||
| .nav-link { | |||
| &.active, | |||
| &:focus, | |||
| @@ -13,6 +13,7 @@ | |||
| flex-direction: column; | |||
| box-shadow: none; | |||
| } | |||
| &:first-child, | |||
| &:last-child { | |||
| .page-link { | |||
| @@ -20,11 +21,13 @@ | |||
| font-size: $font-size-lg; | |||
| } | |||
| } | |||
| .page-month { | |||
| margin-bottom: 0; | |||
| font-size: $font-size-lg; | |||
| font-weight: $font-weight-bold; | |||
| } | |||
| .page-year { | |||
| margin-bottom: 0; | |||
| } | |||
| @@ -35,6 +38,7 @@ | |||
| font-size: ($font-size-lg * 1.25); | |||
| } | |||
| } | |||
| &.pagination-sm { | |||
| .page-month { | |||
| font-size: ($font-size-base); | |||
| @@ -66,6 +70,7 @@ | |||
| } | |||
| } | |||
| } | |||
| &:not(.active) { | |||
| .page-link { | |||
| background-color: $dark; | |||