| <?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> |
| { | |||||
| "ExpandedNodes": [ | |||||
| "" | |||||
| ], | |||||
| "PreviewInSolutionExplorer": false | |||||
| } |
| 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; } | |||||
| } |
| using System; | 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; } | |||||
| } |
| using AutoMapper; | using AutoMapper; | ||||
| using Microsoft.Extensions.DependencyInjection; | 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"); | |||||
| } | } | ||||
| } | |||||
| } |
| using AutoMapper; | 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.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(); | |||||
| } | } | ||||
| } | |||||
| } |
| | |||||
| 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 | |||||
| } |
| 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; } | |||||
| } |
| using System; | |||||
| using Microsoft.Extensions.Configuration; | using Microsoft.Extensions.Configuration; | ||||
| using Microsoft.Extensions.DependencyInjection; | 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; | |||||
| } | } | ||||
| } | } |
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using System.Collections.Generic; | |||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
| using SecureSharing.Business.Dtos; | using SecureSharing.Business.Dtos; | ||||
| using SecureSharing.Business.Infrastructure; | 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); | |||||
| } |
| <Project Sdk="Microsoft.NET.Sdk"> | <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> | </Project> |
| using System; | using System; | ||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||
| using System.Linq; | using System.Linq; | ||||
| using System.Text; | |||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
| using AutoMapper; | using AutoMapper; | ||||
| using Microsoft.EntityFrameworkCore; | |||||
| using SecureSharing.Business.Dtos; | using SecureSharing.Business.Dtos; | ||||
| using SecureSharing.Business.Infrastructure; | |||||
| using SecureSharing.Business.Interfaces; | using SecureSharing.Business.Interfaces; | ||||
| using SecureSharing.Data.Data; | using SecureSharing.Data.Data; | ||||
| using SecureSharing.Data.DbContexts; | 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(); | |||||
| } | } | ||||
| } | |||||
| } |
| using System; | 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; } | |||||
| } |
| using Microsoft.AspNetCore.Identity.EntityFrameworkCore; | using Microsoft.AspNetCore.Identity.EntityFrameworkCore; | ||||
| using Microsoft.EntityFrameworkCore; | using Microsoft.EntityFrameworkCore; | ||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using SecureSharing.Data.Data; | 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; } | |||||
| } |
| using Microsoft.Extensions.DependencyInjection; | |||||
| using Microsoft.EntityFrameworkCore; | |||||
| using Microsoft.EntityFrameworkCore; | |||||
| using Microsoft.Extensions.Configuration; | 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 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"))); | |||||
| } | } | ||||
| } | |||||
| } |
| <Project Sdk="Microsoft.NET.Sdk"> | <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> | </Project> |
| 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) => { }); | |||||
| } | } | ||||
| } | } |
| <section> | <section> | ||||
| <form id="account" method="post"> | <form id="account" method="post"> | ||||
| <h4>Use a local account to log in.</h4> | <h4>Use a local account to log in.</h4> | ||||
| <hr /> | |||||
| <hr/> | |||||
| <div asp-validation-summary="All" class="text-danger"></div> | <div asp-validation-summary="All" class="text-danger"></div> | ||||
| <div class="form-group"> | <div class="form-group"> | ||||
| <label asp-for="Input.Email"></label> | <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> | <span asp-validation-for="Input.Email" class="text-danger"></span> | ||||
| </div> | </div> | ||||
| <div class="form-group"> | <div class="form-group"> | ||||
| <label asp-for="Input.Password"></label> | <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> | <span asp-validation-for="Input.Password" class="text-danger"></span> | ||||
| </div> | </div> | ||||
| <div class="form-group"> | <div class="form-group"> | ||||
| <div class="checkbox"> | <div class="checkbox"> | ||||
| <label asp-for="Input.RememberMe"> | <label asp-for="Input.RememberMe"> | ||||
| <input asp-for="Input.RememberMe" /> | |||||
| <input asp-for="Input.RememberMe"/> | |||||
| @Html.DisplayNameFor(m => m.Input.RememberMe) | @Html.DisplayNameFor(m => m.Input.RememberMe) | ||||
| </label> | </label> | ||||
| </div> | </div> | ||||
| <div class="col-md-6 col-md-offset-2"> | <div class="col-md-6 col-md-offset-2"> | ||||
| <section> | <section> | ||||
| <h4>Use another service to log in.</h4> | <h4>Use another service to log in.</h4> | ||||
| <hr /> | |||||
| <hr/> | |||||
| @{ | @{ | ||||
| if ((Model.ExternalLogins?.Count ?? 0) == 0) | if ((Model.ExternalLogins?.Count ?? 0) == 0) | ||||
| { | { | ||||
| </div> | </div> | ||||
| @section Scripts { | @section Scripts { | ||||
| <partial name="_ValidationScriptsPartial" /> | |||||
| } | |||||
| <partial name="_ValidationScriptsPartial"/> | |||||
| } |
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Collections.Generic; | |||||
| using System.ComponentModel.DataAnnotations; | using System.ComponentModel.DataAnnotations; | ||||
| using System.Linq; | using System.Linq; | ||||
| using System.Text.Encodings.Web; | |||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
| using Microsoft.AspNetCore.Authorization; | |||||
| using Microsoft.AspNetCore.Authentication; | using Microsoft.AspNetCore.Authentication; | ||||
| using Microsoft.AspNetCore.Authorization; | |||||
| using Microsoft.AspNetCore.Identity; | using Microsoft.AspNetCore.Identity; | ||||
| using Microsoft.AspNetCore.Identity.UI.Services; | |||||
| using Microsoft.AspNetCore.Mvc; | using Microsoft.AspNetCore.Mvc; | ||||
| using Microsoft.AspNetCore.Mvc.RazorPages; | using Microsoft.AspNetCore.Mvc.RazorPages; | ||||
| using Microsoft.Extensions.Logging; | 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(); | 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; } | |||||
| } | } | ||||
| } | |||||
| } |
| <div class="col-md-4"> | <div class="col-md-4"> | ||||
| <form asp-route-returnUrl="@Model.ReturnUrl" method="post"> | <form asp-route-returnUrl="@Model.ReturnUrl" method="post"> | ||||
| <h4>Create a new account.</h4> | <h4>Create a new account.</h4> | ||||
| <hr /> | |||||
| <hr/> | |||||
| <div asp-validation-summary="All" class="text-danger"></div> | <div asp-validation-summary="All" class="text-danger"></div> | ||||
| <div class="form-group"> | <div class="form-group"> | ||||
| <label asp-for="Input.Email"></label> | <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> | <span asp-validation-for="Input.Email" class="text-danger"></span> | ||||
| </div> | </div> | ||||
| <div class="form-group"> | <div class="form-group"> | ||||
| <label asp-for="Input.Password"></label> | <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> | <span asp-validation-for="Input.Password" class="text-danger"></span> | ||||
| </div> | </div> | ||||
| <div class="form-group"> | <div class="form-group"> | ||||
| <label asp-for="Input.ConfirmPassword"></label> | <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> | <span asp-validation-for="Input.ConfirmPassword" class="text-danger"></span> | ||||
| </div> | </div> | ||||
| <button type="submit" class="btn btn-primary">Register</button> | <button type="submit" class="btn btn-primary">Register</button> | ||||
| <div class="col-md-6 col-md-offset-2"> | <div class="col-md-6 col-md-offset-2"> | ||||
| <section> | <section> | ||||
| <h4>Use another service to register.</h4> | <h4>Use another service to register.</h4> | ||||
| <hr /> | |||||
| <hr/> | |||||
| @{ | @{ | ||||
| if ((Model.ExternalLogins?.Count ?? 0) == 0) | if ((Model.ExternalLogins?.Count ?? 0) == 0) | ||||
| { | { | ||||
| </div> | </div> | ||||
| @section Scripts { | @section Scripts { | ||||
| <partial name="_ValidationScriptsPartial" /> | |||||
| } | |||||
| <partial name="_ValidationScriptsPartial"/> | |||||
| } |
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Collections.Generic; | |||||
| using System.ComponentModel.DataAnnotations; | using System.ComponentModel.DataAnnotations; | ||||
| using System.Linq; | using System.Linq; | ||||
| using System.Text; | using System.Text; | ||||
| using Microsoft.AspNetCore.WebUtilities; | using Microsoft.AspNetCore.WebUtilities; | ||||
| using Microsoft.Extensions.Logging; | 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; } | |||||
| } | } | ||||
| } | |||||
| } |
| <h1>@ViewData["Title"]</h1> | <h1>@ViewData["Title"]</h1> | ||||
| <h4>Reset your password.</h4> | <h4>Reset your password.</h4> | ||||
| <hr /> | |||||
| <hr/> | |||||
| <div class="row"> | <div class="row"> | ||||
| <div class="col-md-4"> | <div class="col-md-4"> | ||||
| <form method="post"> | <form method="post"> | ||||
| <div asp-validation-summary="ModelOnly" class="text-danger"></div> | <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"> | <div class="form-group"> | ||||
| <label asp-for="Input.Email"></label> | <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> | <span asp-validation-for="Input.Email" class="text-danger"></span> | ||||
| </div> | </div> | ||||
| <div class="form-group"> | <div class="form-group"> | ||||
| <label asp-for="Input.Password"></label> | <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> | <span asp-validation-for="Input.Password" class="text-danger"></span> | ||||
| </div> | </div> | ||||
| <div class="form-group"> | <div class="form-group"> | ||||
| <label asp-for="Input.ConfirmPassword"></label> | <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> | <span asp-validation-for="Input.ConfirmPassword" class="text-danger"></span> | ||||
| </div> | </div> | ||||
| <button type="submit" class="btn btn-primary">Reset</button> | <button type="submit" class="btn btn-primary">Reset</button> | ||||
| </div> | </div> | ||||
| @section Scripts { | @section Scripts { | ||||
| <partial name="_ValidationScriptsPartial" /> | |||||
| } | |||||
| <partial name="_ValidationScriptsPartial"/> | |||||
| } |
| 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.Threading.Tasks; | ||||
| using System.Web; | |||||
| using Microsoft.AspNetCore.Authorization; | using Microsoft.AspNetCore.Authorization; | ||||
| using Microsoft.AspNetCore.Identity; | using Microsoft.AspNetCore.Identity; | ||||
| using Microsoft.AspNetCore.Mvc; | using Microsoft.AspNetCore.Mvc; | ||||
| using Microsoft.AspNetCore.Mvc.RazorPages; | 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; } | |||||
| } | } | ||||
| } | |||||
| } |
| crossorigin="anonymous" | crossorigin="anonymous" | ||||
| integrity="sha384-ifv0TYDWxBHzvAk2Z0n8R434FL1Rlv/Av18DXE43N/1rvHyOG4izKst0f2iSLdds"> | integrity="sha384-ifv0TYDWxBHzvAk2Z0n8R434FL1Rlv/Av18DXE43N/1rvHyOG4izKst0f2iSLdds"> | ||||
| </script> | </script> | ||||
| </environment> | |||||
| </environment> |
| @using Microsoft.AspNetCore.Identity | @using Microsoft.AspNetCore.Identity | ||||
| @using SecureSharing.Areas.Identity | @using SecureSharing.Areas.Identity | ||||
| @using SecureSharing.Areas.Identity.Pages | @using SecureSharing.Areas.Identity.Pages | ||||
| @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers | |||||
| @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers |
| | |||||
| @{ | |||||
| @{ | |||||
| Layout = "/Views/Shared/_Layout.cshtml"; | Layout = "/Views/Shared/_Layout.cshtml"; | ||||
| } | |||||
| } |
| using Microsoft.AspNetCore.Authorization; | |||||
| using System.Threading.Tasks; | |||||
| using Microsoft.AspNetCore.Authorization; | |||||
| using Microsoft.AspNetCore.Mvc; | using Microsoft.AspNetCore.Mvc; | ||||
| using Microsoft.Extensions.Logging; | using Microsoft.Extensions.Logging; | ||||
| using Newtonsoft.Json; | |||||
| using SecureSharing.Business.Dtos; | 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.Business.Interfaces; | ||||
| using SecureSharing.Infrastructure; | 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(); | |||||
| } | } | ||||
| } | |||||
| } |
| using SecureSharing.Business.Dtos; | |||||
| using System.Threading.Tasks; | |||||
| using SecureSharing.Models; | 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); | |||||
| } |
| using Microsoft.AspNetCore.Hosting; | |||||
| using Microsoft.AspNetCore.Http; | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System; | |||||
| using System.Net; | using System.Net; | ||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
| using Microsoft.AspNetCore.Hosting; | |||||
| using Microsoft.AspNetCore.Http; | |||||
| using Newtonsoft.Json; | using Newtonsoft.Json; | ||||
| using Serilog; | 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); | |||||
| } | |||||
| } |
| using SecureSharing.Business.Dtos; | |||||
| using System; | |||||
| using System.Threading.Tasks; | |||||
| using SecureSharing.Business.Interfaces; | using SecureSharing.Business.Interfaces; | ||||
| using SecureSharing.Models; | 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(); | |||||
| //} | |||||
| } |
| 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); | |||||
| } |
| using System; | 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; } | |||||
| } |
| using SecureSharing.Business.Infrastructure; | 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; } | |||||
| } |
| using Microsoft.AspNetCore.Hosting; | using Microsoft.AspNetCore.Hosting; | ||||
| using Microsoft.Extensions.Configuration; | |||||
| using Microsoft.Extensions.Hosting; | 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>(); }); | |||||
| } | } | ||||
| } | |||||
| } |
| https://go.microsoft.com/fwlink/?LinkID=208121. | https://go.microsoft.com/fwlink/?LinkID=208121. | ||||
| --> | --> | ||||
| <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | <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> | </Project> |
| by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121. | 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"> | <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> | </Project> |
| using Microsoft.Extensions.DependencyInjection; | |||||
| using System; | |||||
| using System.Collections.Concurrent; | |||||
| using Microsoft.Extensions.DependencyInjection; | |||||
| using Quartz; | using Quartz; | ||||
| using Quartz.Spi; | 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(); | |||||
| } | } | ||||
| } | |||||
| } |
| using System; | 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) | 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; } | |||||
| } |
| using Microsoft.Extensions.Hosting; | |||||
| using System.Threading; | |||||
| using System.Threading.Tasks; | |||||
| using Microsoft.Extensions.Hosting; | |||||
| using Quartz; | using Quartz; | ||||
| using Quartz.Spi; | 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, | 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()) | .WithIdentity(jobMetadata.JobId.ToString()) | ||||
| .WithCronSchedule(jobMetadata.CronExpression) | .WithCronSchedule(jobMetadata.CronExpression) | ||||
| .WithDescription($"{jobMetadata.JobName}") | .WithDescription($"{jobMetadata.JobName}") | ||||
| .Build(); | .Build(); | ||||
| } | |||||
| private IJobDetail CreateJob(JobMetadata jobMetadata) | |||||
| { | |||||
| return JobBuilder | |||||
| } | |||||
| private IJobDetail CreateJob(JobMetadata jobMetadata) | |||||
| { | |||||
| return JobBuilder | |||||
| .Create(jobMetadata.JobType) | .Create(jobMetadata.JobType) | ||||
| .WithIdentity(jobMetadata.JobId.ToString()) | .WithIdentity(jobMetadata.JobId.ToString()) | ||||
| .WithDescription($"{jobMetadata.JobName}") | .WithDescription($"{jobMetadata.JobName}") | ||||
| .Build(); | .Build(); | ||||
| } | |||||
| } | } | ||||
| } | |||||
| } |
| using SecureSharing.Business.Interfaces; | |||||
| using Quartz; | |||||
| using System; | |||||
| using System; | |||||
| using System.Threading.Tasks; | 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*/ | |||||
| } | } | ||||
| } | } | ||||
| } | |||||
| } |
| <Project Sdk="Microsoft.NET.Sdk.Web"> | <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> | </Project> |
| using Microsoft.AspNetCore.Builder; | using Microsoft.AspNetCore.Builder; | ||||
| using Microsoft.AspNetCore.Hosting; | using Microsoft.AspNetCore.Hosting; | ||||
| using Microsoft.AspNetCore.HttpsPolicy; | |||||
| using Microsoft.AspNetCore.Identity; | using Microsoft.AspNetCore.Identity; | ||||
| using Microsoft.Extensions.Configuration; | using Microsoft.Extensions.Configuration; | ||||
| using Microsoft.Extensions.DependencyInjection; | using Microsoft.Extensions.DependencyInjection; | ||||
| using Microsoft.Extensions.Hosting; | using Microsoft.Extensions.Hosting; | ||||
| using Quartz; | |||||
| using Quartz.Impl; | |||||
| using Quartz.Spi; | |||||
| using SecureSharing.Business.Infrastructure; | using SecureSharing.Business.Infrastructure; | ||||
| using SecureSharing.Business.Infrastructure.Extensions; | using SecureSharing.Business.Infrastructure.Extensions; | ||||
| using SecureSharing.Business.Infrastructure.Settings; | using SecureSharing.Business.Infrastructure.Settings; | ||||
| using SecureSharing.Infrastructure; | using SecureSharing.Infrastructure; | ||||
| using SecureSharing.Infrastructure.Middleware; | using SecureSharing.Infrastructure.Middleware; | ||||
| using SecureSharing.Quartz; | 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 => | .AddGoogle(options => | ||||
| { | { | ||||
| options.ClientId = Configuration.GetSection("EmailSettings").GetSection("ClientId").Value; | options.ClientId = Configuration.GetSection("EmailSettings").GetSection("ClientId").Value; | ||||
| }); | }); | ||||
| // 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(); | |||||
| }); | |||||
| } | } | ||||
| } | |||||
| } |
| <div class="text-center"> | <div class="text-center"> | ||||
| <form method="post" asp-controller="Home" asp-action="CreateMessage"> | <form method="post" asp-controller="Home" asp-action="CreateMessage"> | ||||
| <input asp-for="Text" /> | |||||
| <input asp-for="Text"/> | |||||
| <br> | <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> | <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> | <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> | <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> | <br> | ||||
| <button class = " btn btn-light" type="submit">Send</button> | |||||
| <button class=" btn btn-light" type="submit">Send</button> | |||||
| </form> | </form> | ||||
| <br> | |||||
| <br> | |||||
| </div> | |||||
| </div> |
| | |||||
| @{ | |||||
| @{ | |||||
| Layout = "~/Views/Shared/_Layout.cshtml"; | Layout = "~/Views/Shared/_Layout.cshtml"; | ||||
| } | } | ||||
| @model LinkModel | @model LinkModel | ||||
| <div class="text-center"> | <div class="text-center"> | ||||
| @if(!Model.IsValid) | |||||
| @if (!Model.IsValid) | |||||
| { | { | ||||
| <p>This link has expired</p> | <p>This link has expired</p> | ||||
| } | } | ||||
| else | 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> | <div> | ||||
| @if(Model.TimeLeft != null) | |||||
| @if (Model.TimeLeft != null) | |||||
| { | { | ||||
| var time = Model.TimeLeft.Value; | 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> | <p>This message will expire in: @time.ToString("%d") days @time.ToString("%h") hours @time.ToString("%m") minutes</p> | ||||
| } | } | ||||
| <p>This message will expire when you leave this page</p> | <p>This message will expire when you leave this page</p> | ||||
| } | } | ||||
| </div> | </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> | <a class="btn btn-light" asp-controller="Home" asp-action="Index">Back</a> | ||||
| </div> | |||||
| </div> |
| } | } | ||||
| <h1>@ViewData["Title"]</h1> | <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> |
| It can result in displaying sensitive information from exceptions to end users. | 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> | 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. | and restarting the app. | ||||
| </p> | |||||
| </p> |
| <!DOCTYPE html> | <!DOCTYPE html> | ||||
| <html lang="en"> | <html lang="en"> | ||||
| <head> | <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> | <title>@ViewData["Title"] - SecureSharing</title> | ||||
| <!-- Google Font: Source Sans Pro --> | <!-- Google Font: Source Sans Pro --> | ||||
| <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700&display=fallback"> | <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700&display=fallback"> | ||||
| <link rel="stylesheet" href="~/plugins/summernote/summernote-bs4.min.css"> | <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"> | <link rel="stylesheet" href="~/css/site.css"> | ||||
| </head> | </head> | ||||
| <body class="hold-transition layout-fixed"> | <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> | ||||
| </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> | </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) | $.widget.bridge('uibutton', $.ui.button) | ||||
| </script> | </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> | </body> | ||||
| </html> | |||||
| </html> |
| <script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script> | <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> |
| @using SecureSharing | @using SecureSharing | ||||
| @using SecureSharing.Models | @using SecureSharing.Models | ||||
| @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers | |||||
| @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers |
| @{ | @{ | ||||
| Layout = "_Layout"; | Layout = "_Layout"; | ||||
| } | |||||
| } |
| { | { | ||||
| "AllowedHosts": "*", | "AllowedHosts": "*", | ||||
| "ConnectionStrings": { | "ConnectionStrings": { | ||||
| "DefaultConnection": "data source=(localdb)\\MSSQLLocalDB; initial catalog=Test;Integrated Security=True" | "DefaultConnection": "data source=(localdb)\\MSSQLLocalDB; initial catalog=Test;Integrated Security=True" | ||||
| }, | }, | ||||
| "Logging": { | "Logging": { | ||||
| "LogLevel": { | "LogLevel": { |
| 'use strict' | 'use strict' | ||||
| module.exports = { | 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 | |||||
| }) | |||||
| ] | |||||
| } | } |
| 'use strict' | 'use strict' | ||||
| const { babel } = require('@rollup/plugin-babel') | |||||
| const {babel} = require('@rollup/plugin-babel') | |||||
| const pkg = require('../../package') | const pkg = require('../../package') | ||||
| const year = new Date().getFullYear() | const year = new Date().getFullYear() | ||||
| */` | */` | ||||
| module.exports = { | 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' | |||||
| }) | |||||
| ] | |||||
| } | } |
| import Treeview from './Treeview' | import Treeview from './Treeview' | ||||
| export { | 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 | |||||
| } | } |
| const SELECTOR_DATA_REFRESH = '[data-card-widget="card-refresh"]' | const SELECTOR_DATA_REFRESH = '[data-card-widget="card-refresh"]' | ||||
| const Default = { | 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 { | 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() | |||||
| } | |||||
| } | } | ||||
| } | |||||
| } | } | ||||
| /** | /** | ||||
| */ | */ | ||||
| $(document).on('click', SELECTOR_DATA_REFRESH, function (event) { | $(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)) | |||||
| }) | |||||
| }) | }) | ||||
| /** | /** | ||||
| $.fn[NAME] = CardRefresh._jQueryInterface | $.fn[NAME] = CardRefresh._jQueryInterface | ||||
| $.fn[NAME].Constructor = CardRefresh | $.fn[NAME].Constructor = CardRefresh | ||||
| $.fn[NAME].noConflict = function () { | $.fn[NAME].noConflict = function () { | ||||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||||
| return CardRefresh._jQueryInterface | |||||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||||
| return CardRefresh._jQueryInterface | |||||
| } | } | ||||
| export default CardRefresh | export default CardRefresh |
| const SELECTOR_CARD_FOOTER = '.card-footer' | const SELECTOR_CARD_FOOTER = '.card-footer' | ||||
| const Default = { | 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 { | 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() | |||||
| }) | |||||
| } | } | ||||
| } | |||||
| } | } | ||||
| /** | /** | ||||
| */ | */ | ||||
| $(document).on('click', SELECTOR_DATA_COLLAPSE, function (event) { | $(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) { | $(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) { | $(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') | |||||
| }) | }) | ||||
| /** | /** | ||||
| $.fn[NAME] = CardWidget._jQueryInterface | $.fn[NAME] = CardWidget._jQueryInterface | ||||
| $.fn[NAME].Constructor = CardWidget | $.fn[NAME].Constructor = CardWidget | ||||
| $.fn[NAME].noConflict = function () { | $.fn[NAME].noConflict = function () { | ||||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||||
| return CardWidget._jQueryInterface | |||||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||||
| return CardWidget._jQueryInterface | |||||
| } | } | ||||
| export default CardWidget | export default CardWidget |
| const CLASS_NAME_FOOTER_XL_FIXED = 'layout-xl-footer-fixed' | const CLASS_NAME_FOOTER_XL_FIXED = 'layout-xl-footer-fixed' | ||||
| const Default = { | 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 | |||||
| } | } | ||||
| /** | /** | ||||
| */ | */ | ||||
| class ControlSidebar { | 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() | 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 | |||||
| } | |||||
| }) | |||||
| } | |||||
| } | |||||
| } | } | ||||
| /** | /** | ||||
| * ==================================================== | * ==================================================== | ||||
| */ | */ | ||||
| $(document).on('click', SELECTOR_DATA_TOGGLE, function (event) { | $(document).on('click', SELECTOR_DATA_TOGGLE, function (event) { | ||||
| event.preventDefault() | |||||
| event.preventDefault() | |||||
| ControlSidebar._jQueryInterface.call($(this), 'toggle') | |||||
| ControlSidebar._jQueryInterface.call($(this), 'toggle') | |||||
| }) | }) | ||||
| $(document).ready(() => { | $(document).ready(() => { | ||||
| ControlSidebar._jQueryInterface.call($(SELECTOR_DATA_TOGGLE), '_init') | |||||
| ControlSidebar._jQueryInterface.call($(SELECTOR_DATA_TOGGLE), '_init') | |||||
| }) | }) | ||||
| /** | /** | ||||
| $.fn[NAME] = ControlSidebar._jQueryInterface | $.fn[NAME] = ControlSidebar._jQueryInterface | ||||
| $.fn[NAME].Constructor = ControlSidebar | $.fn[NAME].Constructor = ControlSidebar | ||||
| $.fn[NAME].noConflict = function () { | $.fn[NAME].noConflict = function () { | ||||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||||
| return ControlSidebar._jQueryInterface | |||||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||||
| return ControlSidebar._jQueryInterface | |||||
| } | } | ||||
| export default ControlSidebar | export default ControlSidebar |
| */ | */ | ||||
| class DirectChat { | 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)) | |||||
| } | |||||
| } | } | ||||
| /** | /** | ||||
| */ | */ | ||||
| $(document).on('click', SELECTOR_DATA_TOGGLE, function (event) { | $(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') | |||||
| }) | }) | ||||
| /** | /** | ||||
| $.fn[NAME] = DirectChat._jQueryInterface | $.fn[NAME] = DirectChat._jQueryInterface | ||||
| $.fn[NAME].Constructor = DirectChat | $.fn[NAME].Constructor = DirectChat | ||||
| $.fn[NAME].noConflict = function () { | $.fn[NAME].noConflict = function () { | ||||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||||
| return DirectChat._jQueryInterface | |||||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||||
| return DirectChat._jQueryInterface | |||||
| } | } | ||||
| export default DirectChat | export default DirectChat |
| */ | */ | ||||
| class Dropdown { | 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 | |||||
| }) | |||||
| } | |||||
| } | |||||
| } | } | ||||
| /** | /** | ||||
| */ | */ | ||||
| $(`${SELECTOR_DROPDOWN_MENU} ${SELECTOR_DROPDOWN_TOGGLE}`).on('click', function (event) { | $(`${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 => { | $(`${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) | |||||
| }) | }) | ||||
| /** | /** | ||||
| $.fn[NAME] = Dropdown._jQueryInterface | $.fn[NAME] = Dropdown._jQueryInterface | ||||
| $.fn[NAME].Constructor = Dropdown | $.fn[NAME].Constructor = Dropdown | ||||
| $.fn[NAME].noConflict = function () { | $.fn[NAME].noConflict = function () { | ||||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||||
| return Dropdown._jQueryInterface | |||||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||||
| return Dropdown._jQueryInterface | |||||
| } | } | ||||
| export default Dropdown | export default Dropdown |
| import $ from 'jquery' | import $ from 'jquery' | ||||
| /** | /** | ||||
| * Constants | |||||
| * ==================================================== | |||||
| */ | |||||
| * Constants | |||||
| * ==================================================== | |||||
| */ | |||||
| const NAME = 'ExpandableTable' | const NAME = 'ExpandableTable' | ||||
| const DATA_KEY = 'lte.expandableTable' | const DATA_KEY = 'lte.expandableTable' | ||||
| const SELECTOR_ARIA_ATTR = 'aria-expanded' | const SELECTOR_ARIA_ATTR = 'aria-expanded' | ||||
| /** | /** | ||||
| * Class Definition | |||||
| * ==================================================== | |||||
| */ | |||||
| * Class Definition | |||||
| * ==================================================== | |||||
| */ | |||||
| class ExpandableTable { | 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 () { | $(SELECTOR_TABLE).ready(function () { | ||||
| ExpandableTable._jQueryInterface.call($(this), 'init') | |||||
| ExpandableTable._jQueryInterface.call($(this), 'init') | |||||
| }) | }) | ||||
| $(document).on('click', SELECTOR_DATA_TOGGLE, function () { | $(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] = ExpandableTable._jQueryInterface | ||||
| $.fn[NAME].Constructor = ExpandableTable | $.fn[NAME].Constructor = ExpandableTable | ||||
| $.fn[NAME].noConflict = function () { | $.fn[NAME].noConflict = function () { | ||||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||||
| return ExpandableTable._jQueryInterface | |||||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||||
| return ExpandableTable._jQueryInterface | |||||
| } | } | ||||
| export default ExpandableTable | export default ExpandableTable |
| const SELECTOR_ICON = `${SELECTOR_DATA_WIDGET} i` | const SELECTOR_ICON = `${SELECTOR_DATA_WIDGET} i` | ||||
| const Default = { | const Default = { | ||||
| minimizeIcon: 'fa-compress-arrows-alt', | |||||
| maximizeIcon: 'fa-expand-arrows-alt' | |||||
| minimizeIcon: 'fa-compress-arrows-alt', | |||||
| maximizeIcon: 'fa-expand-arrows-alt' | |||||
| } | } | ||||
| /** | /** | ||||
| */ | */ | ||||
| class Fullscreen { | 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 () { | $(document).on('click', SELECTOR_DATA_WIDGET, function () { | ||||
| Fullscreen._jQueryInterface.call($(this), 'toggle') | |||||
| Fullscreen._jQueryInterface.call($(this), 'toggle') | |||||
| }) | }) | ||||
| /** | /** | ||||
| $.fn[NAME] = Fullscreen._jQueryInterface | $.fn[NAME] = Fullscreen._jQueryInterface | ||||
| $.fn[NAME].Constructor = Fullscreen | $.fn[NAME].Constructor = Fullscreen | ||||
| $.fn[NAME].noConflict = function () { | $.fn[NAME].noConflict = function () { | ||||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||||
| return Fullscreen._jQueryInterface | |||||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||||
| return Fullscreen._jQueryInterface | |||||
| } | } | ||||
| export default Fullscreen | export default Fullscreen |
| const CLASS_NAME_FULLSCREEN_MODE = 'iframe-mode-fullscreen' | const CLASS_NAME_FULLSCREEN_MODE = 'iframe-mode-fullscreen' | ||||
| const Default = { | 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' | |||||
| } | } | ||||
| /** | /** | ||||
| */ | */ | ||||
| class IFrame { | 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) | |||||
| } | |||||
| } | |||||
| } | } | ||||
| } | |||||
| } | } | ||||
| /** | /** | ||||
| */ | */ | ||||
| $(window).on('load', () => { | $(window).on('load', () => { | ||||
| IFrame._jQueryInterface.call($(SELECTOR_DATA_TOGGLE)) | |||||
| IFrame._jQueryInterface.call($(SELECTOR_DATA_TOGGLE)) | |||||
| }) | }) | ||||
| /** | /** | ||||
| $.fn[NAME] = IFrame._jQueryInterface | $.fn[NAME] = IFrame._jQueryInterface | ||||
| $.fn[NAME].Constructor = IFrame | $.fn[NAME].Constructor = IFrame | ||||
| $.fn[NAME].noConflict = function () { | $.fn[NAME].noConflict = function () { | ||||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||||
| return IFrame._jQueryInterface | |||||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||||
| return IFrame._jQueryInterface | |||||
| } | } | ||||
| export default IFrame | export default IFrame |
| const CLASS_NAME_CONTROL_SIDEBAR_OPEN = 'control-sidebar-open' | const CLASS_NAME_CONTROL_SIDEBAR_OPEN = 'control-sidebar-open' | ||||
| const Default = { | 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 | |||||
| } | } | ||||
| /** | /** | ||||
| */ | */ | ||||
| class Layout { | 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() | 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(() => { | 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' | |||||
| } | |||||
| } | } | ||||
| /** | /** | ||||
| */ | */ | ||||
| $(window).on('load', () => { | $(window).on('load', () => { | ||||
| Layout._jQueryInterface.call($('body')) | |||||
| Layout._jQueryInterface.call($('body')) | |||||
| }) | }) | ||||
| $(`${SELECTOR_SIDEBAR} a`) | $(`${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 | * jQuery API | ||||
| $.fn[NAME] = Layout._jQueryInterface | $.fn[NAME] = Layout._jQueryInterface | ||||
| $.fn[NAME].Constructor = Layout | $.fn[NAME].Constructor = Layout | ||||
| $.fn[NAME].noConflict = function () { | $.fn[NAME].noConflict = function () { | ||||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||||
| return Layout._jQueryInterface | |||||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||||
| return Layout._jQueryInterface | |||||
| } | } | ||||
| export default Layout | export default Layout |
| const CLASS_NAME_OPEN = 'navbar-search-open' | const CLASS_NAME_OPEN = 'navbar-search-open' | ||||
| const Default = { | const Default = { | ||||
| resetOnClose: true, | |||||
| target: SELECTOR_SEARCH_BLOCK | |||||
| resetOnClose: true, | |||||
| target: SELECTOR_SEARCH_BLOCK | |||||
| } | } | ||||
| /** | /** | ||||
| */ | */ | ||||
| class NavbarSearch { | 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() | |||||
| } | |||||
| } | |||||
| } | } | ||||
| /** | /** | ||||
| * ==================================================== | * ==================================================== | ||||
| */ | */ | ||||
| $(document).on('click', SELECTOR_TOGGLE_BUTTON, event => { | $(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') | |||||
| }) | }) | ||||
| /** | /** | ||||
| $.fn[NAME] = NavbarSearch._jQueryInterface | $.fn[NAME] = NavbarSearch._jQueryInterface | ||||
| $.fn[NAME].Constructor = NavbarSearch | $.fn[NAME].Constructor = NavbarSearch | ||||
| $.fn[NAME].noConflict = function () { | $.fn[NAME].noConflict = function () { | ||||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||||
| return NavbarSearch._jQueryInterface | |||||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||||
| return NavbarSearch._jQueryInterface | |||||
| } | } | ||||
| export default NavbarSearch | export default NavbarSearch |
| const CLASS_NAME_CLOSED = 'sidebar-closed' | const CLASS_NAME_CLOSED = 'sidebar-closed' | ||||
| const Default = { | const Default = { | ||||
| autoCollapseSize: 992, | |||||
| enableRemember: false, | |||||
| noTransitionAfterReload: true | |||||
| autoCollapseSize: 992, | |||||
| enableRemember: false, | |||||
| noTransitionAfterReload: true | |||||
| } | } | ||||
| /** | /** | ||||
| */ | */ | ||||
| class PushMenu { | 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) | |||||
| } | |||||
| } | } | ||||
| /** | /** | ||||
| */ | */ | ||||
| $(document).on('click', SELECTOR_TOGGLE_BUTTON, event => { | $(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', () => { | $(window).on('load', () => { | ||||
| PushMenu._jQueryInterface.call($(SELECTOR_TOGGLE_BUTTON)) | |||||
| PushMenu._jQueryInterface.call($(SELECTOR_TOGGLE_BUTTON)) | |||||
| }) | }) | ||||
| /** | /** | ||||
| $.fn[NAME] = PushMenu._jQueryInterface | $.fn[NAME] = PushMenu._jQueryInterface | ||||
| $.fn[NAME].Constructor = PushMenu | $.fn[NAME].Constructor = PushMenu | ||||
| $.fn[NAME].noConflict = function () { | $.fn[NAME].noConflict = function () { | ||||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||||
| return PushMenu._jQueryInterface | |||||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||||
| return PushMenu._jQueryInterface | |||||
| } | } | ||||
| export default PushMenu | export default PushMenu |
| * -------------------------------------------- | * -------------------------------------------- | ||||
| */ | */ | ||||
| import $, { trim } from 'jquery' | |||||
| import $, {trim} from 'jquery' | |||||
| /** | /** | ||||
| * Constants | * Constants | ||||
| const SELECTOR_SEARCH_RESULTS_GROUP = `${SELECTOR_SEARCH_RESULTS} .${CLASS_NAME_LIST_GROUP}` | const SELECTOR_SEARCH_RESULTS_GROUP = `${SELECTOR_SEARCH_RESULTS} .${CLASS_NAME_LIST_GROUP}` | ||||
| const Default = { | 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 = [] | const SearchItems = [] | ||||
| */ | */ | ||||
| class SidebarSearch { | 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, '#', [])) | |||||
| } | } | ||||
| } | |||||
| } | } | ||||
| /** | /** | ||||
| * ==================================================== | * ==================================================== | ||||
| */ | */ | ||||
| $(document).on('click', SELECTOR_SEARCH_BUTTON, event => { | $(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 => { | $(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 => { | $(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', () => { | $(window).on('load', () => { | ||||
| SidebarSearch._jQueryInterface.call($(SELECTOR_DATA_WIDGET), 'init') | |||||
| SidebarSearch._jQueryInterface.call($(SELECTOR_DATA_WIDGET), 'init') | |||||
| }) | }) | ||||
| /** | /** | ||||
| $.fn[NAME] = SidebarSearch._jQueryInterface | $.fn[NAME] = SidebarSearch._jQueryInterface | ||||
| $.fn[NAME].Constructor = SidebarSearch | $.fn[NAME].Constructor = SidebarSearch | ||||
| $.fn[NAME].noConflict = function () { | $.fn[NAME].noConflict = function () { | ||||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||||
| return SidebarSearch._jQueryInterface | |||||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||||
| return SidebarSearch._jQueryInterface | |||||
| } | } | ||||
| export default SidebarSearch | export default SidebarSearch |
| const POSITION_BOTTOM_LEFT = 'bottomLeft' | const POSITION_BOTTOM_LEFT = 'bottomLeft' | ||||
| const Default = { | 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 | |||||
| } | } | ||||
| /** | /** | ||||
| * ==================================================== | * ==================================================== | ||||
| */ | */ | ||||
| class Toasts { | 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') | |||||
| } | |||||
| } | |||||
| } | } | ||||
| /** | /** | ||||
| $.fn[NAME] = Toasts._jQueryInterface | $.fn[NAME] = Toasts._jQueryInterface | ||||
| $.fn[NAME].Constructor = Toasts | $.fn[NAME].Constructor = Toasts | ||||
| $.fn[NAME].noConflict = function () { | $.fn[NAME].noConflict = function () { | ||||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||||
| return Toasts._jQueryInterface | |||||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||||
| return Toasts._jQueryInterface | |||||
| } | } | ||||
| export default Toasts | export default Toasts |
| const CLASS_NAME_TODO_LIST_DONE = 'done' | const CLASS_NAME_TODO_LIST_DONE = 'done' | ||||
| const Default = { | const Default = { | ||||
| onCheck(item) { | |||||
| return item | |||||
| }, | |||||
| onUnCheck(item) { | |||||
| return item | |||||
| } | |||||
| onCheck(item) { | |||||
| return item | |||||
| }, | |||||
| onUnCheck(item) { | |||||
| return item | |||||
| } | |||||
| } | } | ||||
| /** | /** | ||||
| */ | */ | ||||
| class TodoList { | 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)) | |||||
| }) | |||||
| } | |||||
| } | } | ||||
| /** | /** | ||||
| */ | */ | ||||
| $(window).on('load', () => { | $(window).on('load', () => { | ||||
| TodoList._jQueryInterface.call($(SELECTOR_DATA_TOGGLE)) | |||||
| TodoList._jQueryInterface.call($(SELECTOR_DATA_TOGGLE)) | |||||
| }) | }) | ||||
| /** | /** | ||||
| $.fn[NAME] = TodoList._jQueryInterface | $.fn[NAME] = TodoList._jQueryInterface | ||||
| $.fn[NAME].Constructor = TodoList | $.fn[NAME].Constructor = TodoList | ||||
| $.fn[NAME].noConflict = function () { | $.fn[NAME].noConflict = function () { | ||||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||||
| return TodoList._jQueryInterface | |||||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||||
| return TodoList._jQueryInterface | |||||
| } | } | ||||
| export default TodoList | export default TodoList |
| const CLASS_NAME_SIDEBAR_COLLAPSED = 'sidebar-collapse' | const CLASS_NAME_SIDEBAR_COLLAPSED = 'sidebar-collapse' | ||||
| const Default = { | 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"]' | |||||
| } | } | ||||
| /** | /** | ||||
| * ==================================================== | * ==================================================== | ||||
| */ | */ | ||||
| class Treeview { | 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') | |||||
| } | |||||
| } | |||||
| } | } | ||||
| /** | /** | ||||
| */ | */ | ||||
| $(window).on(EVENT_LOAD_DATA_API, () => { | $(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') | |||||
| }) | |||||
| }) | }) | ||||
| /** | /** | ||||
| $.fn[NAME] = Treeview._jQueryInterface | $.fn[NAME] = Treeview._jQueryInterface | ||||
| $.fn[NAME].Constructor = Treeview | $.fn[NAME].Constructor = Treeview | ||||
| $.fn[NAME].noConflict = function () { | $.fn[NAME].noConflict = function () { | ||||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||||
| return Treeview._jQueryInterface | |||||
| $.fn[NAME] = JQUERY_NO_CONFLICT | |||||
| return Treeview._jQueryInterface | |||||
| } | } | ||||
| export default Treeview | export default Treeview |
| 'use strict' | 'use strict' | ||||
| const Plugins = [ | 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 | module.exports = Plugins |
| const Plugins = require('./DocsPlugins') | const Plugins = require('./DocsPlugins') | ||||
| class Publish { | 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() | (new Publish()).run() |
| 'use strict' | 'use strict' | ||||
| const Plugins = [ | 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 | module.exports = Plugins |
| const Plugins = require('./Plugins') | const Plugins = require('./Plugins') | ||||
| class Publish { | 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() | (new Publish()).run() |
| const vnu = require('vnu-jar') | const vnu = require('vnu-jar') | ||||
| childProcess.exec('java -version', (error, stdout, stderr) => { | 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) | |||||
| }) | }) |
| &__shake { | &__shake { | ||||
| animation: shake 1500ms; | animation: shake 1500ms; | ||||
| } | } | ||||
| &__wobble { | &__wobble { | ||||
| animation: wobble 1500ms; | animation: wobble 1500ms; | ||||
| } | } |
| border-color: lighten($gray-600, 2.5%); | border-color: lighten($gray-600, 2.5%); | ||||
| } | } | ||||
| } | } | ||||
| .btn-light { | .btn-light { | ||||
| background-color: lighten($dark, 7.5%); | background-color: lighten($dark, 7.5%); | ||||
| color: $white; | color: $white; |
| .card-header, | .card-header, | ||||
| .card-body, | .card-body, | ||||
| .card-footer { | .card-footer { | ||||
| @include clearfix (); | |||||
| @include clearfix(); | |||||
| } | } | ||||
| // Box header | // Box header | ||||
| } | } | ||||
| .chart-legend { | .chart-legend { | ||||
| @include list-unstyled (); | |||||
| @include list-unstyled(); | |||||
| margin: 10px 0; | margin: 10px 0; | ||||
| > li { | > li { | ||||
| background-color: $gray-100; | background-color: $gray-100; | ||||
| .card-comment { | .card-comment { | ||||
| @include clearfix (); | |||||
| @include clearfix(); | |||||
| border-bottom: 1px solid $gray-200; | border-bottom: 1px solid $gray-200; | ||||
| padding: 8px 0; | padding: 8px 0; | ||||
| background-color: lighten($dark, 5%); | background-color: lighten($dark, 5%); | ||||
| color: $white; | color: $white; | ||||
| } | } | ||||
| .nav.flex-column > li { | .nav.flex-column > li { | ||||
| border-bottom-color: $gray-600; | border-bottom-color: $gray-600; | ||||
| } | } | ||||
| .card-footer { | .card-footer { | ||||
| background-color: rgba($black, .1); | background-color: rgba($black, .1); | ||||
| } | } | ||||
| &.card-outline-tabs .card-header a:hover { | &.card-outline-tabs .card-header a:hover { | ||||
| border-color: $gray-600; | border-color: $gray-600; | ||||
| border-bottom-color: transparent; | border-bottom-color: transparent; | ||||
| } | } | ||||
| &:not(.card-outline) > .card-header a.active { | &:not(.card-outline) > .card-header a.active { | ||||
| color: $white; | color: $white; | ||||
| } | } | ||||
| .card-comments { | .card-comments { | ||||
| background-color: lighten($dark, 1.25%); | background-color: lighten($dark, 1.25%); | ||||
| .username { | .username { | ||||
| color: $gray-400; | color: $gray-400; | ||||
| } | } | ||||
| .card-comment { | .card-comment { | ||||
| border-bottom-color: lighten($dark, 7.5%); | border-bottom-color: lighten($dark, 7.5%); | ||||
| } | } |
| .carousel-control-prev & { | .carousel-control-prev & { | ||||
| margin-left: -20px; | margin-left: -20px; | ||||
| } | } | ||||
| .carousel-control-next & { | .carousel-control-next & { | ||||
| margin-right: 20px; | margin-right: 20px; | ||||
| } | } |
| background-color: lighten($dark, 7.5%) !important; | background-color: lighten($dark, 7.5%) !important; | ||||
| color: $white !important; | color: $white !important; | ||||
| } | } | ||||
| .text-black, | .text-black, | ||||
| .text-dark, | .text-dark, | ||||
| .link-black, | .link-black, |
| } | } | ||||
| .direct-chat-msg { | .direct-chat-msg { | ||||
| @include clearfix (); | |||||
| @include clearfix(); | |||||
| margin-bottom: 10px; | margin-bottom: 10px; | ||||
| } | } | ||||
| //Contacts list -- for displaying contacts in direct chat contacts pane | //Contacts list -- for displaying contacts in direct chat contacts pane | ||||
| .contacts-list { | .contacts-list { | ||||
| @include list-unstyled (); | |||||
| @include list-unstyled(); | |||||
| > li { | > li { | ||||
| @include clearfix (); | |||||
| @include clearfix(); | |||||
| border-bottom: 1px solid rgba($black, .2); | border-bottom: 1px solid rgba($black, .2); | ||||
| margin: 0; | margin: 0; | ||||
| padding: 10px; | padding: 10px; | ||||
| border-right-color: lighten($dark, 10%); | border-right-color: lighten($dark, 10%); | ||||
| } | } | ||||
| } | } | ||||
| .direct-chat-timestamp { | .direct-chat-timestamp { | ||||
| color: $gray-500; | color: $gray-500; | ||||
| } | } | ||||
| .right > .direct-chat-text { | .right > .direct-chat-text { | ||||
| &::after, | &::after, | ||||
| &::before { | &::before { |
| position: relative; | position: relative; | ||||
| > a::after { | > a::after { | ||||
| @include caret-right (); | |||||
| @include caret-right(); | |||||
| float: right; | float: right; | ||||
| margin-left: .5rem; | margin-left: .5rem; | ||||
| margin-top: .5rem; | margin-top: .5rem; | ||||
| .navbar-custom-menu > .navbar-nav { | .navbar-custom-menu > .navbar-nav { | ||||
| > li { | > li { | ||||
| position: relative; | position: relative; | ||||
| > .dropdown-menu { | > .dropdown-menu { | ||||
| position: absolute; | position: absolute; | ||||
| right: 0; | right: 0; | ||||
| @include media-breakpoint-down(sm) { | @include media-breakpoint-down(sm) { | ||||
| .navbar-custom-menu > .navbar-nav { | .navbar-custom-menu > .navbar-nav { | ||||
| float: right; | float: right; | ||||
| > li { | > li { | ||||
| position: static; | position: static; | ||||
| > .dropdown-menu { | > .dropdown-menu { | ||||
| position: absolute; | position: absolute; | ||||
| right: 5%; | right: 5%; | ||||
| // Menu Body | // Menu Body | ||||
| > .user-body { | > .user-body { | ||||
| @include clearfix (); | |||||
| @include clearfix(); | |||||
| border-bottom: 1px solid $gray-700; | border-bottom: 1px solid $gray-700; | ||||
| border-top: 1px solid $gray-300; | border-top: 1px solid $gray-300; | ||||
| padding: 15px; | padding: 15px; | ||||
| // Menu Footer | // Menu Footer | ||||
| > .user-footer { | > .user-footer { | ||||
| @include clearfix (); | |||||
| @include clearfix(); | |||||
| background-color: $gray-100; | background-color: $gray-100; | ||||
| padding: 10px; | padding: 10px; | ||||
| background-color: $dark; | background-color: $dark; | ||||
| color: $white; | color: $white; | ||||
| } | } | ||||
| .dropdown-item { | .dropdown-item { | ||||
| color: $white; | color: $white; | ||||
| background-color: lighten($dark, 5%); | background-color: lighten($dark, 5%); | ||||
| } | } | ||||
| } | } | ||||
| .dropdown-divider { | .dropdown-divider { | ||||
| border-color: $gray-600; | border-color: $gray-600; | ||||
| } | } | ||||
| background-color: lighten($dark, 5%); | background-color: lighten($dark, 5%); | ||||
| color: $gray-300; | color: $gray-300; | ||||
| } | } | ||||
| &:focus { | &:focus { | ||||
| background-color: lighten($dark, 7.5%); | background-color: lighten($dark, 7.5%); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| > .user-body { | > .user-body { | ||||
| border-color: $gray-600; | border-color: $gray-600; | ||||
| } | } | ||||
| > .user-body a { | > .user-body a { | ||||
| background-color: transparent !important; | background-color: transparent !important; | ||||
| color: $white !important; | color: $white !important; |
| &.border-width-2 { | &.border-width-2 { | ||||
| border-bottom-width: 2px; | border-bottom-width: 2px; | ||||
| } | } | ||||
| &.border-width-3 { | &.border-width-3 { | ||||
| border-bottom-width: 3px; | border-bottom-width: 3px; | ||||
| } | } | ||||
| background-color: transparent !important; | background-color: transparent !important; | ||||
| box-shadow: none; | box-shadow: none; | ||||
| } | } | ||||
| &:checked ~ .custom-control-label::before { | &:checked ~ .custom-control-label::before { | ||||
| @include gradient-bg(transparent); | @include gradient-bg(transparent); | ||||
| } | } | ||||
| border: 1px solid lighten($sidebar-dark-bg, 15%); | border: 1px solid lighten($sidebar-dark-bg, 15%); | ||||
| color: lighten(color-yiq(lighten($sidebar-dark-bg, 5%)), 15%); | color: lighten(color-yiq(lighten($sidebar-dark-bg, 5%)), 15%); | ||||
| } | } | ||||
| .btn-navbar { | .btn-navbar { | ||||
| &:hover { | &:hover { | ||||
| background-color: lighten($sidebar-dark-bg, 7.5%); | background-color: lighten($sidebar-dark-bg, 7.5%); | ||||
| } | } | ||||
| &:focus { | &:focus { | ||||
| background-color: lighten($sidebar-dark-bg, 10%); | background-color: lighten($sidebar-dark-bg, 10%); | ||||
| } | } | ||||
| background-color: $dark; | background-color: $dark; | ||||
| color: $white; | color: $white; | ||||
| } | } | ||||
| .form-control:not(.form-control-navbar):not(.form-control-sidebar):not(.is-invalid):not(:focus), | .form-control:not(.form-control-navbar):not(.form-control-sidebar):not(.is-invalid):not(:focus), | ||||
| .custom-file-label, | .custom-file-label, | ||||
| .custom-file-label::after { | .custom-file-label::after { | ||||
| border-color: $gray-600; | border-color: $gray-600; | ||||
| } | } | ||||
| select { | select { | ||||
| background-color: $dark; | background-color: $dark; | ||||
| color: $white; | color: $white; | ||||
| &::-webkit-slider-runnable-track { | &::-webkit-slider-runnable-track { | ||||
| background-color: lighten($dark, 7.5%); | background-color: lighten($dark, 7.5%); | ||||
| } | } | ||||
| &::-moz-range-track { | &::-moz-range-track { | ||||
| background-color: lighten($dark, 7.5%); | background-color: lighten($dark, 7.5%); | ||||
| } | } | ||||
| &::-ms-track { | &::-ms-track { | ||||
| background-color: lighten($dark, 7.5%); | background-color: lighten($dark, 7.5%); | ||||
| } | } |
| color: $gray-500; | color: $gray-500; | ||||
| } | } | ||||
| } | } | ||||
| .main-footer { | .main-footer { | ||||
| background-color: $dark; | background-color: $dark; | ||||
| border-color: lighten($dark, 10%); | border-color: lighten($dark, 10%); | ||||
| } | } | ||||
| .content-wrapper { | .content-wrapper { | ||||
| background-color: lighten($dark, 7.5%); | background-color: lighten($dark, 7.5%); | ||||
| color: $white; | color: $white; |
| // Hover and active states | // Hover and active states | ||||
| &.menu-open > .nav-link, | &.menu-open > .nav-link, | ||||
| &:hover > .nav-link, | &:hover > .nav-link, | ||||
| > .nav-link:focus { | |||||
| > .nav-link:focus { | |||||
| background-color: $sidebar-dark-hover-bg; | background-color: $sidebar-dark-hover-bg; | ||||
| color: $sidebar-dark-hover-color; | color: $sidebar-dark-hover-color; | ||||
| } | } | ||||
| } | } | ||||
| &.active { | &.active { | ||||
| > .nav-icon{ | |||||
| > .nav-icon { | |||||
| margin-left: .36rem; | margin-left: .36rem; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| &.active { | &.active { | ||||
| > .nav-icon{ | |||||
| > .nav-icon { | |||||
| margin-left: calc(.75rem - 3px); | margin-left: calc(.75rem - 3px); | ||||
| } | } | ||||
| } | } | ||||
| width: 100%; | width: 100%; | ||||
| flex-wrap: nowrap; | flex-wrap: nowrap; | ||||
| } | } | ||||
| .sidebar nav .form-inline { | .sidebar nav .form-inline { | ||||
| margin-bottom: .2rem; | margin-bottom: .2rem; | ||||
| } | } | ||||
| &.sidebar-collapse .main-sidebar { | &.sidebar-collapse .main-sidebar { | ||||
| margin-left: 0; | margin-left: 0; | ||||
| } | } | ||||
| .content-wrapper, | .content-wrapper, | ||||
| .main-header, | .main-header, | ||||
| .main-footer { | .main-footer { |
| // Box overlay for LOADING STATE effect on Tab Panels | // Box overlay for LOADING STATE effect on Tab Panels | ||||
| > .overlay-wrapper { | > .overlay-wrapper { | ||||
| position: relative; | position: relative; | ||||
| > .overlay { | > .overlay { | ||||
| border-top-left-radius: 0; | border-top-left-radius: 0; | ||||
| border-top-right-radius: 0; | border-top-right-radius: 0; | ||||
| a:not(.btn):hover { | a:not(.btn):hover { | ||||
| color: lighten($link-color, 10%); | color: lighten($link-color, 10%); | ||||
| } | } | ||||
| .attachment-block { | .attachment-block { | ||||
| background-color: lighten($dark, 3.75%); | background-color: lighten($dark, 3.75%); | ||||
| color: $gray-400; | color: $gray-400; | ||||
| } | } | ||||
| } | } | ||||
| blockquote { | blockquote { | ||||
| background-color: lighten($dark, 5%); | background-color: lighten($dark, 5%); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| .close, | .close, | ||||
| .mailbox-attachment-close { | .mailbox-attachment-close { | ||||
| color: $gray-500; | color: $gray-500; | ||||
| text-shadow: 0 1px 0 $gray-700; | text-shadow: 0 1px 0 $gray-700; | ||||
| } | } | ||||
| .tab-custom-content { | .tab-custom-content { | ||||
| border-color: $gray-600; | border-color: $gray-600; | ||||
| } | } | ||||
| .list-group-item { | .list-group-item { | ||||
| background-color: $dark; | background-color: $dark; | ||||
| border-color: $gray-600; | border-color: $gray-600; |
| .modal-footer { | .modal-footer { | ||||
| border-color: $gray-600; | border-color: $gray-600; | ||||
| } | } | ||||
| .modal-content { | .modal-content { | ||||
| background-color: $dark; | background-color: $dark; | ||||
| .modal-footer { | .modal-footer { | ||||
| border-color: $gray-600; | border-color: $gray-600; | ||||
| } | } | ||||
| .close { | .close { | ||||
| color: $dark !important; | color: $dark !important; | ||||
| text-shadow: 0 1px 0 $gray-700 !important; | text-shadow: 0 1px 0 $gray-700 !important; |
| border-top-right-radius: 0; | border-top-right-radius: 0; | ||||
| margin-right: -$nav-tabs-border-width; | margin-right: -$nav-tabs-border-width; | ||||
| @include hover-focus () { | |||||
| @include hover-focus() { | |||||
| border-color: $gray-200 transparent $gray-200 $gray-200; | border-color: $gray-200 transparent $gray-200 $gray-200; | ||||
| } | } | ||||
| } | } | ||||
| border-top-right-radius: $nav-tabs-border-radius; | border-top-right-radius: $nav-tabs-border-radius; | ||||
| margin-left: -$nav-tabs-border-width; | margin-left: -$nav-tabs-border-width; | ||||
| @include hover-focus () { | |||||
| @include hover-focus() { | |||||
| border-color: $gray-200 $gray-200 $gray-200 transparent; | border-color: $gray-200 $gray-200 $gray-200 transparent; | ||||
| } | } | ||||
| } | } | ||||
| &:hover { | &:hover { | ||||
| border-color: lighten($dark, 15%) transparent lighten($dark, 15%) lighten($dark, 15%); | border-color: lighten($dark, 15%) transparent lighten($dark, 15%) lighten($dark, 15%); | ||||
| } | } | ||||
| &:focus, | &:focus, | ||||
| &:hover { | &:hover { | ||||
| background-color: lighten($dark, 5%); | background-color: lighten($dark, 5%); | ||||
| } | } | ||||
| } | } | ||||
| &.nav-tabs-right { | &.nav-tabs-right { | ||||
| border-color: lighten($dark, 15%); | border-color: lighten($dark, 15%); | ||||
| .nav-link { | .nav-link { | ||||
| &.active, | &.active, | ||||
| &:focus, | &:focus, |
| flex-direction: column; | flex-direction: column; | ||||
| box-shadow: none; | box-shadow: none; | ||||
| } | } | ||||
| &:first-child, | &:first-child, | ||||
| &:last-child { | &:last-child { | ||||
| .page-link { | .page-link { | ||||
| font-size: $font-size-lg; | font-size: $font-size-lg; | ||||
| } | } | ||||
| } | } | ||||
| .page-month { | .page-month { | ||||
| margin-bottom: 0; | margin-bottom: 0; | ||||
| font-size: $font-size-lg; | font-size: $font-size-lg; | ||||
| font-weight: $font-weight-bold; | font-weight: $font-weight-bold; | ||||
| } | } | ||||
| .page-year { | .page-year { | ||||
| margin-bottom: 0; | margin-bottom: 0; | ||||
| } | } | ||||
| font-size: ($font-size-lg * 1.25); | font-size: ($font-size-lg * 1.25); | ||||
| } | } | ||||
| } | } | ||||
| &.pagination-sm { | &.pagination-sm { | ||||
| .page-month { | .page-month { | ||||
| font-size: ($font-size-base); | font-size: ($font-size-base); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| &:not(.active) { | &:not(.active) { | ||||
| .page-link { | .page-link { | ||||
| background-color: $dark; | background-color: $dark; |