Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
1e635f53bf | |||
5beb66f11a |
63
.gitattributes
vendored
Normal file
63
.gitattributes
vendored
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
###############################################################################
|
||||||
|
# Set default behavior to automatically normalize line endings.
|
||||||
|
###############################################################################
|
||||||
|
* text=auto
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Set default behavior for command prompt diff.
|
||||||
|
#
|
||||||
|
# This is need for earlier builds of msysgit that does not have it on by
|
||||||
|
# default for csharp files.
|
||||||
|
# Note: This is only used by command line
|
||||||
|
###############################################################################
|
||||||
|
#*.cs diff=csharp
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Set the merge driver for project and solution files
|
||||||
|
#
|
||||||
|
# Merging from the command prompt will add diff markers to the files if there
|
||||||
|
# are conflicts (Merging from VS is not affected by the settings below, in VS
|
||||||
|
# the diff markers are never inserted). Diff markers may cause the following
|
||||||
|
# file extensions to fail to load in VS. An alternative would be to treat
|
||||||
|
# these files as binary and thus will always conflict and require user
|
||||||
|
# intervention with every merge. To do so, just uncomment the entries below
|
||||||
|
###############################################################################
|
||||||
|
#*.sln merge=binary
|
||||||
|
#*.csproj merge=binary
|
||||||
|
#*.vbproj merge=binary
|
||||||
|
#*.vcxproj merge=binary
|
||||||
|
#*.vcproj merge=binary
|
||||||
|
#*.dbproj merge=binary
|
||||||
|
#*.fsproj merge=binary
|
||||||
|
#*.lsproj merge=binary
|
||||||
|
#*.wixproj merge=binary
|
||||||
|
#*.modelproj merge=binary
|
||||||
|
#*.sqlproj merge=binary
|
||||||
|
#*.wwaproj merge=binary
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# behavior for image files
|
||||||
|
#
|
||||||
|
# image files are treated as binary by default.
|
||||||
|
###############################################################################
|
||||||
|
#*.jpg binary
|
||||||
|
#*.png binary
|
||||||
|
#*.gif binary
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# diff behavior for common document formats
|
||||||
|
#
|
||||||
|
# Convert binary document formats to text before diffing them. This feature
|
||||||
|
# is only available from the command line. Turn it on by uncommenting the
|
||||||
|
# entries below.
|
||||||
|
###############################################################################
|
||||||
|
#*.doc diff=astextplain
|
||||||
|
#*.DOC diff=astextplain
|
||||||
|
#*.docx diff=astextplain
|
||||||
|
#*.DOCX diff=astextplain
|
||||||
|
#*.dot diff=astextplain
|
||||||
|
#*.DOT diff=astextplain
|
||||||
|
#*.pdf diff=astextplain
|
||||||
|
#*.PDF diff=astextplain
|
||||||
|
#*.rtf diff=astextplain
|
||||||
|
#*.RTF diff=astextplain
|
363
.gitignore
vendored
Normal file
363
.gitignore
vendored
Normal file
@ -0,0 +1,363 @@
|
|||||||
|
## Ignore Visual Studio temporary files, build results, and
|
||||||
|
## files generated by popular Visual Studio add-ons.
|
||||||
|
##
|
||||||
|
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||||
|
|
||||||
|
# User-specific files
|
||||||
|
*.rsuser
|
||||||
|
*.suo
|
||||||
|
*.user
|
||||||
|
*.userosscache
|
||||||
|
*.sln.docstates
|
||||||
|
|
||||||
|
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||||
|
*.userprefs
|
||||||
|
|
||||||
|
# Mono auto generated files
|
||||||
|
mono_crash.*
|
||||||
|
|
||||||
|
# Build results
|
||||||
|
[Dd]ebug/
|
||||||
|
[Dd]ebugPublic/
|
||||||
|
[Rr]elease/
|
||||||
|
[Rr]eleases/
|
||||||
|
x64/
|
||||||
|
x86/
|
||||||
|
[Ww][Ii][Nn]32/
|
||||||
|
[Aa][Rr][Mm]/
|
||||||
|
[Aa][Rr][Mm]64/
|
||||||
|
bld/
|
||||||
|
[Bb]in/
|
||||||
|
[Oo]bj/
|
||||||
|
[Oo]ut/
|
||||||
|
[Ll]og/
|
||||||
|
[Ll]ogs/
|
||||||
|
|
||||||
|
# Visual Studio 2015/2017 cache/options directory
|
||||||
|
.vs/
|
||||||
|
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||||
|
#wwwroot/
|
||||||
|
|
||||||
|
# Visual Studio 2017 auto generated files
|
||||||
|
Generated\ Files/
|
||||||
|
|
||||||
|
# MSTest test Results
|
||||||
|
[Tt]est[Rr]esult*/
|
||||||
|
[Bb]uild[Ll]og.*
|
||||||
|
|
||||||
|
# NUnit
|
||||||
|
*.VisualState.xml
|
||||||
|
TestResult.xml
|
||||||
|
nunit-*.xml
|
||||||
|
|
||||||
|
# Build Results of an ATL Project
|
||||||
|
[Dd]ebugPS/
|
||||||
|
[Rr]eleasePS/
|
||||||
|
dlldata.c
|
||||||
|
|
||||||
|
# Benchmark Results
|
||||||
|
BenchmarkDotNet.Artifacts/
|
||||||
|
|
||||||
|
# .NET Core
|
||||||
|
project.lock.json
|
||||||
|
project.fragment.lock.json
|
||||||
|
artifacts/
|
||||||
|
|
||||||
|
# ASP.NET Scaffolding
|
||||||
|
ScaffoldingReadMe.txt
|
||||||
|
|
||||||
|
# StyleCop
|
||||||
|
StyleCopReport.xml
|
||||||
|
|
||||||
|
# Files built by Visual Studio
|
||||||
|
*_i.c
|
||||||
|
*_p.c
|
||||||
|
*_h.h
|
||||||
|
*.ilk
|
||||||
|
*.meta
|
||||||
|
*.obj
|
||||||
|
*.iobj
|
||||||
|
*.pch
|
||||||
|
*.pdb
|
||||||
|
*.ipdb
|
||||||
|
*.pgc
|
||||||
|
*.pgd
|
||||||
|
*.rsp
|
||||||
|
*.sbr
|
||||||
|
*.tlb
|
||||||
|
*.tli
|
||||||
|
*.tlh
|
||||||
|
*.tmp
|
||||||
|
*.tmp_proj
|
||||||
|
*_wpftmp.csproj
|
||||||
|
*.log
|
||||||
|
*.vspscc
|
||||||
|
*.vssscc
|
||||||
|
.builds
|
||||||
|
*.pidb
|
||||||
|
*.svclog
|
||||||
|
*.scc
|
||||||
|
|
||||||
|
# Chutzpah Test files
|
||||||
|
_Chutzpah*
|
||||||
|
|
||||||
|
# Visual C++ cache files
|
||||||
|
ipch/
|
||||||
|
*.aps
|
||||||
|
*.ncb
|
||||||
|
*.opendb
|
||||||
|
*.opensdf
|
||||||
|
*.sdf
|
||||||
|
*.cachefile
|
||||||
|
*.VC.db
|
||||||
|
*.VC.VC.opendb
|
||||||
|
|
||||||
|
# Visual Studio profiler
|
||||||
|
*.psess
|
||||||
|
*.vsp
|
||||||
|
*.vspx
|
||||||
|
*.sap
|
||||||
|
|
||||||
|
# Visual Studio Trace Files
|
||||||
|
*.e2e
|
||||||
|
|
||||||
|
# TFS 2012 Local Workspace
|
||||||
|
$tf/
|
||||||
|
|
||||||
|
# Guidance Automation Toolkit
|
||||||
|
*.gpState
|
||||||
|
|
||||||
|
# ReSharper is a .NET coding add-in
|
||||||
|
_ReSharper*/
|
||||||
|
*.[Rr]e[Ss]harper
|
||||||
|
*.DotSettings.user
|
||||||
|
|
||||||
|
# TeamCity is a build add-in
|
||||||
|
_TeamCity*
|
||||||
|
|
||||||
|
# DotCover is a Code Coverage Tool
|
||||||
|
*.dotCover
|
||||||
|
|
||||||
|
# AxoCover is a Code Coverage Tool
|
||||||
|
.axoCover/*
|
||||||
|
!.axoCover/settings.json
|
||||||
|
|
||||||
|
# Coverlet is a free, cross platform Code Coverage Tool
|
||||||
|
coverage*.json
|
||||||
|
coverage*.xml
|
||||||
|
coverage*.info
|
||||||
|
|
||||||
|
# Visual Studio code coverage results
|
||||||
|
*.coverage
|
||||||
|
*.coveragexml
|
||||||
|
|
||||||
|
# NCrunch
|
||||||
|
_NCrunch_*
|
||||||
|
.*crunch*.local.xml
|
||||||
|
nCrunchTemp_*
|
||||||
|
|
||||||
|
# MightyMoose
|
||||||
|
*.mm.*
|
||||||
|
AutoTest.Net/
|
||||||
|
|
||||||
|
# Web workbench (sass)
|
||||||
|
.sass-cache/
|
||||||
|
|
||||||
|
# Installshield output folder
|
||||||
|
[Ee]xpress/
|
||||||
|
|
||||||
|
# DocProject is a documentation generator add-in
|
||||||
|
DocProject/buildhelp/
|
||||||
|
DocProject/Help/*.HxT
|
||||||
|
DocProject/Help/*.HxC
|
||||||
|
DocProject/Help/*.hhc
|
||||||
|
DocProject/Help/*.hhk
|
||||||
|
DocProject/Help/*.hhp
|
||||||
|
DocProject/Help/Html2
|
||||||
|
DocProject/Help/html
|
||||||
|
|
||||||
|
# Click-Once directory
|
||||||
|
publish/
|
||||||
|
|
||||||
|
# Publish Web Output
|
||||||
|
*.[Pp]ublish.xml
|
||||||
|
*.azurePubxml
|
||||||
|
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||||
|
# but database connection strings (with potential passwords) will be unencrypted
|
||||||
|
*.pubxml
|
||||||
|
*.publishproj
|
||||||
|
|
||||||
|
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||||
|
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||||
|
# in these scripts will be unencrypted
|
||||||
|
PublishScripts/
|
||||||
|
|
||||||
|
# NuGet Packages
|
||||||
|
*.nupkg
|
||||||
|
# NuGet Symbol Packages
|
||||||
|
*.snupkg
|
||||||
|
# The packages folder can be ignored because of Package Restore
|
||||||
|
**/[Pp]ackages/*
|
||||||
|
# except build/, which is used as an MSBuild target.
|
||||||
|
!**/[Pp]ackages/build/
|
||||||
|
# Uncomment if necessary however generally it will be regenerated when needed
|
||||||
|
#!**/[Pp]ackages/repositories.config
|
||||||
|
# NuGet v3's project.json files produces more ignorable files
|
||||||
|
*.nuget.props
|
||||||
|
*.nuget.targets
|
||||||
|
|
||||||
|
# Microsoft Azure Build Output
|
||||||
|
csx/
|
||||||
|
*.build.csdef
|
||||||
|
|
||||||
|
# Microsoft Azure Emulator
|
||||||
|
ecf/
|
||||||
|
rcf/
|
||||||
|
|
||||||
|
# Windows Store app package directories and files
|
||||||
|
AppPackages/
|
||||||
|
BundleArtifacts/
|
||||||
|
Package.StoreAssociation.xml
|
||||||
|
_pkginfo.txt
|
||||||
|
*.appx
|
||||||
|
*.appxbundle
|
||||||
|
*.appxupload
|
||||||
|
|
||||||
|
# Visual Studio cache files
|
||||||
|
# files ending in .cache can be ignored
|
||||||
|
*.[Cc]ache
|
||||||
|
# but keep track of directories ending in .cache
|
||||||
|
!?*.[Cc]ache/
|
||||||
|
|
||||||
|
# Others
|
||||||
|
ClientBin/
|
||||||
|
~$*
|
||||||
|
*~
|
||||||
|
*.dbmdl
|
||||||
|
*.dbproj.schemaview
|
||||||
|
*.jfm
|
||||||
|
*.pfx
|
||||||
|
*.publishsettings
|
||||||
|
orleans.codegen.cs
|
||||||
|
|
||||||
|
# Including strong name files can present a security risk
|
||||||
|
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||||
|
#*.snk
|
||||||
|
|
||||||
|
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||||
|
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||||
|
#bower_components/
|
||||||
|
|
||||||
|
# RIA/Silverlight projects
|
||||||
|
Generated_Code/
|
||||||
|
|
||||||
|
# Backup & report files from converting an old project file
|
||||||
|
# to a newer Visual Studio version. Backup files are not needed,
|
||||||
|
# because we have git ;-)
|
||||||
|
_UpgradeReport_Files/
|
||||||
|
Backup*/
|
||||||
|
UpgradeLog*.XML
|
||||||
|
UpgradeLog*.htm
|
||||||
|
ServiceFabricBackup/
|
||||||
|
*.rptproj.bak
|
||||||
|
|
||||||
|
# SQL Server files
|
||||||
|
*.mdf
|
||||||
|
*.ldf
|
||||||
|
*.ndf
|
||||||
|
|
||||||
|
# Business Intelligence projects
|
||||||
|
*.rdl.data
|
||||||
|
*.bim.layout
|
||||||
|
*.bim_*.settings
|
||||||
|
*.rptproj.rsuser
|
||||||
|
*- [Bb]ackup.rdl
|
||||||
|
*- [Bb]ackup ([0-9]).rdl
|
||||||
|
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||||
|
|
||||||
|
# Microsoft Fakes
|
||||||
|
FakesAssemblies/
|
||||||
|
|
||||||
|
# GhostDoc plugin setting file
|
||||||
|
*.GhostDoc.xml
|
||||||
|
|
||||||
|
# Node.js Tools for Visual Studio
|
||||||
|
.ntvs_analysis.dat
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# Visual Studio 6 build log
|
||||||
|
*.plg
|
||||||
|
|
||||||
|
# Visual Studio 6 workspace options file
|
||||||
|
*.opt
|
||||||
|
|
||||||
|
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||||
|
*.vbw
|
||||||
|
|
||||||
|
# Visual Studio LightSwitch build output
|
||||||
|
**/*.HTMLClient/GeneratedArtifacts
|
||||||
|
**/*.DesktopClient/GeneratedArtifacts
|
||||||
|
**/*.DesktopClient/ModelManifest.xml
|
||||||
|
**/*.Server/GeneratedArtifacts
|
||||||
|
**/*.Server/ModelManifest.xml
|
||||||
|
_Pvt_Extensions
|
||||||
|
|
||||||
|
# Paket dependency manager
|
||||||
|
.paket/paket.exe
|
||||||
|
paket-files/
|
||||||
|
|
||||||
|
# FAKE - F# Make
|
||||||
|
.fake/
|
||||||
|
|
||||||
|
# CodeRush personal settings
|
||||||
|
.cr/personal
|
||||||
|
|
||||||
|
# Python Tools for Visual Studio (PTVS)
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
|
||||||
|
# Cake - Uncomment if you are using it
|
||||||
|
# tools/**
|
||||||
|
# !tools/packages.config
|
||||||
|
|
||||||
|
# Tabs Studio
|
||||||
|
*.tss
|
||||||
|
|
||||||
|
# Telerik's JustMock configuration file
|
||||||
|
*.jmconfig
|
||||||
|
|
||||||
|
# BizTalk build output
|
||||||
|
*.btp.cs
|
||||||
|
*.btm.cs
|
||||||
|
*.odx.cs
|
||||||
|
*.xsd.cs
|
||||||
|
|
||||||
|
# OpenCover UI analysis results
|
||||||
|
OpenCover/
|
||||||
|
|
||||||
|
# Azure Stream Analytics local run output
|
||||||
|
ASALocalRun/
|
||||||
|
|
||||||
|
# MSBuild Binary and Structured Log
|
||||||
|
*.binlog
|
||||||
|
|
||||||
|
# NVidia Nsight GPU debugger configuration file
|
||||||
|
*.nvuser
|
||||||
|
|
||||||
|
# MFractors (Xamarin productivity tool) working folder
|
||||||
|
.mfractor/
|
||||||
|
|
||||||
|
# Local History for Visual Studio
|
||||||
|
.localhistory/
|
||||||
|
|
||||||
|
# BeatPulse healthcheck temp database
|
||||||
|
healthchecksdb
|
||||||
|
|
||||||
|
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||||
|
MigrationBackup/
|
||||||
|
|
||||||
|
# Ionide (cross platform F# VS Code tools) working folder
|
||||||
|
.ionide/
|
||||||
|
|
||||||
|
# Fody - auto-generated XML schema
|
||||||
|
FodyWeavers.xsd
|
240
AppLibs/AppLibs/AppLibs.csproj
Normal file
240
AppLibs/AppLibs/AppLibs.csproj
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Remove="wwwroot\css\atg-font\atg-admin-font.css" />
|
||||||
|
<None Remove="wwwroot\css\atg-font\atg-font.css" />
|
||||||
|
<None Remove="wwwroot\css\atg-lib\atg-core-min.css" />
|
||||||
|
<None Remove="wwwroot\css\atg-lib\atg-core.css" />
|
||||||
|
<None Remove="wwwroot\css\atg-lib\atg-upload.css" />
|
||||||
|
<None Remove="wwwroot\css\atg-lib\datepicker.css" />
|
||||||
|
<None Remove="wwwroot\css\atg-lib\swiper-bundle.min.css" />
|
||||||
|
<None Remove="wwwroot\css\atg-lib\waves.min.css" />
|
||||||
|
<None Remove="wwwroot\css\atg-ui\atg-gui.css" />
|
||||||
|
<None Remove="wwwroot\css\atg-ui\table.css" />
|
||||||
|
<None Remove="wwwroot\font\atg-admin-font.fcp" />
|
||||||
|
<None Remove="wwwroot\font\atgfont-Regular.woff" />
|
||||||
|
<None Remove="wwwroot\font\atgfont-Regular.woff2" />
|
||||||
|
<None Remove="wwwroot\font\ATGIcon-Regular.woff" />
|
||||||
|
<None Remove="wwwroot\font\Branch.woff" />
|
||||||
|
<None Remove="wwwroot\js\ext_libs\js-datepicker.js" />
|
||||||
|
<None Remove="wwwroot\js\ext_libs\js-masonry.min.js" />
|
||||||
|
<None Remove="wwwroot\js\ext_libs\js-overscroll.js" />
|
||||||
|
<None Remove="wwwroot\js\ext_libs\js-scrollbar.js" />
|
||||||
|
<None Remove="wwwroot\js\ext_libs\js-scrollbar.min.js" />
|
||||||
|
<None Remove="wwwroot\js\ext_libs\swiper-bundle.min.js" />
|
||||||
|
<None Remove="wwwroot\js\libs\js-AbsTable.js" />
|
||||||
|
<None Remove="wwwroot\js\libs\js-AButton.js" />
|
||||||
|
<None Remove="wwwroot\js\libs\js-ADropdown.js" />
|
||||||
|
<None Remove="wwwroot\js\libs\js-AGrid.js" />
|
||||||
|
<None Remove="wwwroot\js\libs\js-AListBox.js" />
|
||||||
|
<None Remove="wwwroot\js\libs\js-AMenu.js" />
|
||||||
|
<None Remove="wwwroot\js\libs\js-AModal.js" />
|
||||||
|
<None Remove="wwwroot\js\libs\js-AMultiTag.js" />
|
||||||
|
<None Remove="wwwroot\js\libs\js-AOverlay.js" />
|
||||||
|
<None Remove="wwwroot\js\libs\js-APaging.js" />
|
||||||
|
<None Remove="wwwroot\js\libs\js-ASelect.js" />
|
||||||
|
<None Remove="wwwroot\js\libs\js-ASlideBar.js" />
|
||||||
|
<None Remove="wwwroot\js\libs\js-ASpinButton.js" />
|
||||||
|
<None Remove="wwwroot\js\libs\js-ATab.js" />
|
||||||
|
<None Remove="wwwroot\js\libs\js-ATable.js" />
|
||||||
|
<None Remove="wwwroot\js\libs\js-ATransitionEffect.js" />
|
||||||
|
<None Remove="wwwroot\js\libs\js-core.js" />
|
||||||
|
<None Remove="wwwroot\js\libs\js-upload-worker.js" />
|
||||||
|
<None Remove="wwwroot\js\libs\js-upload.js" />
|
||||||
|
<None Remove="wwwroot\js\libs\js-waves.js" />
|
||||||
|
<None Remove="wwwroot\js\libs\js-waves.min.js" />
|
||||||
|
<None Remove="wwwroot\js\libs\js-waves.min.js.map" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="wwwroot\css\atg-font\atg-admin-font.css">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\css\atg-font\atg-font.css">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\css\atg-lib\atg-core-min.css">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\css\atg-lib\atg-core.css">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\css\atg-lib\atg-upload.css">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\css\atg-lib\datepicker.css">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\css\atg-lib\swiper-bundle.min.css">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\css\atg-lib\waves.min.css">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\css\atg-ui\atg-gui.css">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\css\atg-ui\table.css">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\font\atg-admin-font.fcp">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\font\atgfont-Regular.woff">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\font\atgfont-Regular.woff2">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\font\ATGIcon-Regular.woff">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\font\Branch.woff">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\js\ext_libs\js-datepicker.js">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\js\ext_libs\js-masonry.min.js">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\js\ext_libs\js-overscroll.js">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\js\ext_libs\js-scrollbar.js">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\js\ext_libs\js-scrollbar.min.js">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\js\ext_libs\swiper-bundle.min.js">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\js\libs\js-AbsTable.js">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\js\libs\js-AButton.js">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\js\libs\js-ADropdown.js">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\js\libs\js-AGrid.js">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\js\libs\js-AListBox.js">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\js\libs\js-AMenu.js">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\js\libs\js-AModal.js">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\js\libs\js-AMultiTag.js">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\js\libs\js-AOverlay.js">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\js\libs\js-APaging.js">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\js\libs\js-ASelect.js">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\js\libs\js-ASlideBar.js">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\js\libs\js-ASpinButton.js">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\js\libs\js-ATab.js">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\js\libs\js-ATable.js">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\js\libs\js-ATransitionEffect.js">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\js\libs\js-core.js">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\js\libs\js-upload-worker.js">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\js\libs\js-upload.js">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\js\libs\js-waves.js">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\js\libs\js-waves.min.js">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="wwwroot\js\libs\js-waves.min.js.map">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
|
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Libs\Collections\Concurrent\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
11
AppLibs/AppLibs/Libs/CertificateStore.cs
Normal file
11
AppLibs/AppLibs/Libs/CertificateStore.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
namespace AppLibs.Libs
|
||||||
|
{
|
||||||
|
public class CertificateStore
|
||||||
|
{
|
||||||
|
public static string GetHTTPSCertificate(string name)
|
||||||
|
{
|
||||||
|
var str = Path.GetFullPath(name);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
157
AppLibs/AppLibs/Libs/ControllerExtensions.cs
Normal file
157
AppLibs/AppLibs/Libs/ControllerExtensions.cs
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||||
|
using Microsoft.AspNetCore.Mvc.ViewEngines;
|
||||||
|
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using AppLibs.Libs.Pages;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
|
||||||
|
namespace AppLibs.Libs
|
||||||
|
{
|
||||||
|
public static class ControllerExtensions
|
||||||
|
{
|
||||||
|
public static string AbsoluteContent(this IUrlHelper url, string contentPath)
|
||||||
|
{
|
||||||
|
HttpRequest request = url.ActionContext.HttpContext.Request;
|
||||||
|
return new Uri(new Uri(request.Scheme + "://" + request.Host.Value), url.Content(contentPath)).ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task RenderLayoutAsync(Controller c, IPage a, string layN)
|
||||||
|
{
|
||||||
|
string nLay = "";
|
||||||
|
switch (layN)
|
||||||
|
{
|
||||||
|
case "None":
|
||||||
|
return;
|
||||||
|
case "":
|
||||||
|
nLay = "_LayoutAsync";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
nLay = "_Layout" + layN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
var t3 = ControllerExtensions.RenderViewAsync(c, nLay, null, true);
|
||||||
|
var t4 = ControllerExtensions.RenderSectionScript(c, nLay);
|
||||||
|
await Task.WhenAll(t3, t4);
|
||||||
|
a.Content = t3.Result;
|
||||||
|
a.Scripts = t4.Result;
|
||||||
|
}
|
||||||
|
public static async Task<IActionResult> ViewAsync(this Controller controller)
|
||||||
|
{
|
||||||
|
string vr = controller.HttpContext.Request.Query["vr"].ToString();
|
||||||
|
string layName = GetViewData<string>(controller, "LayoutName", "");
|
||||||
|
if (layName == "") {
|
||||||
|
layName = "Async";
|
||||||
|
controller.ViewData["LayoutName"] = layName;
|
||||||
|
};
|
||||||
|
switch (vr)
|
||||||
|
{
|
||||||
|
case "cAsync":
|
||||||
|
APage a = new APage();
|
||||||
|
var t1 = ControllerExtensions.RenderViewAsync(controller, true);
|
||||||
|
var t2 = ControllerExtensions.RenderSectionScript(controller);
|
||||||
|
await Task.WhenAll(t1, t2);
|
||||||
|
a.Title = GetViewData<string>(controller, "Title");
|
||||||
|
a.PageId = GetViewData<string>(controller, "PageID");
|
||||||
|
a.FlexPageId = GetViewData<string>(controller, "FlexPage", "None");
|
||||||
|
a.LayoutName = layName;
|
||||||
|
a.Content = t1.Result;
|
||||||
|
a.Scripts = t2.Result;
|
||||||
|
return a.Json();
|
||||||
|
case "lAsync":
|
||||||
|
APageLayout a1 = new APageLayout();
|
||||||
|
var t = ControllerExtensions.RenderLayoutAsync(controller, a1, layName);
|
||||||
|
await t;
|
||||||
|
return a1.Json();
|
||||||
|
default:
|
||||||
|
return await Task.FromResult(controller.View());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static T GetViewData<T>(Controller controller, string key, T defaultValue = default!)
|
||||||
|
{
|
||||||
|
if (!controller.ViewData.ContainsKey(key))
|
||||||
|
return defaultValue;
|
||||||
|
|
||||||
|
object? rawValue = controller.ViewData[key];
|
||||||
|
if (rawValue == null)
|
||||||
|
return defaultValue;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Trả lại trực tiếp nếu đã đúng kiểu
|
||||||
|
if (rawValue is T tVal)
|
||||||
|
return tVal;
|
||||||
|
|
||||||
|
// Ép kiểu từ chuỗi
|
||||||
|
string? strValue = rawValue.ToString();
|
||||||
|
if (string.IsNullOrWhiteSpace(strValue))
|
||||||
|
return defaultValue;
|
||||||
|
|
||||||
|
if (typeof(T).IsEnum)
|
||||||
|
{
|
||||||
|
return (T)Enum.Parse(typeof(T), strValue, ignoreCase: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
object? converted = Convert.ChangeType(strValue, typeof(T));
|
||||||
|
return converted is T result ? result : defaultValue;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task<string> RenderSectionScript(this Controller controller)
|
||||||
|
{
|
||||||
|
controller.ViewData["Layout"] = "SectionScript";
|
||||||
|
return await RenderViewAsync(controller);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task<string> RenderSectionScript(this Controller controller, string viewName)
|
||||||
|
{
|
||||||
|
controller.ViewData["Layout"] = "SectionScript";
|
||||||
|
return await RenderViewAsync(controller, viewName, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task<string> RenderViewAsync(this Controller controller, bool partial = false)
|
||||||
|
{
|
||||||
|
return await RenderViewAsync(controller, null, partial);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task<string> RenderViewAsync(this Controller controller, object? model, bool partial = false)
|
||||||
|
{
|
||||||
|
return await RenderViewAsync(controller, controller.ControllerContext.ActionDescriptor.ActionName, model, partial);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task<string> RenderViewAsync(this Controller controller, string viewName, object? model, bool partial = false)
|
||||||
|
{
|
||||||
|
|
||||||
|
controller.ViewData.Model = model;
|
||||||
|
|
||||||
|
using (var writer = new StringWriter())
|
||||||
|
{
|
||||||
|
IViewEngine? viewEngine = controller.HttpContext.RequestServices.GetService(typeof(ICompositeViewEngine)) as ICompositeViewEngine;
|
||||||
|
ViewEngineResult viewResult = viewEngine == null ? throw new ArgumentNullException("View Engigne Result not null") : viewEngine.FindView(controller.ControllerContext, viewName, !partial);
|
||||||
|
|
||||||
|
if (viewResult.Success == false)
|
||||||
|
{
|
||||||
|
return $"A view with the name {viewName} could not be found";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ViewContext viewContext = new ViewContext(
|
||||||
|
controller.ControllerContext,
|
||||||
|
viewResult.View,
|
||||||
|
controller.ViewData,
|
||||||
|
controller.TempData,
|
||||||
|
writer,
|
||||||
|
new HtmlHelperOptions()
|
||||||
|
);
|
||||||
|
await viewResult.View.RenderAsync(viewContext);
|
||||||
|
return Regex.Replace(writer.ToString(), @"(?>[^\S ]\s*| \s{2,})", "").Trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
26
AppLibs/AppLibs/Libs/Crypt/Adler32.cs
Normal file
26
AppLibs/AppLibs/Libs/Crypt/Adler32.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace AppLibs.Libs.Crypt
|
||||||
|
{
|
||||||
|
public class Adler32
|
||||||
|
{
|
||||||
|
private const uint MOD_ADLER = 65521;
|
||||||
|
public uint ComputeHash(byte[] data)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint a = 1, b = 0;
|
||||||
|
|
||||||
|
foreach (var c in data)
|
||||||
|
{
|
||||||
|
a = (a + c) % MOD_ADLER;
|
||||||
|
b = (b + a) % MOD_ADLER;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (b << 16) | a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
57
AppLibs/AppLibs/Libs/Crypt/CRC32.cs
Normal file
57
AppLibs/AppLibs/Libs/Crypt/CRC32.cs
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace AppLibs.Libs.Crypt
|
||||||
|
{
|
||||||
|
public class CRC32
|
||||||
|
{
|
||||||
|
private readonly uint[] ChecksumTable;
|
||||||
|
private readonly uint Polynomial = 0xEDB88320;
|
||||||
|
|
||||||
|
public CRC32()
|
||||||
|
{
|
||||||
|
ChecksumTable = new uint[0x100];
|
||||||
|
|
||||||
|
for (uint index = 0; index < 0x100; ++index)
|
||||||
|
{
|
||||||
|
uint item = index;
|
||||||
|
for (int bit = 0; bit < 8; ++bit)
|
||||||
|
item = ((item & 1) != 0) ? (Polynomial ^ (item >> 1)) : (item >> 1);
|
||||||
|
ChecksumTable[index] = item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] ComputeHash(Stream stream)
|
||||||
|
{
|
||||||
|
uint result = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
int current;
|
||||||
|
while ((current = stream.ReadByte()) != -1)
|
||||||
|
result = ChecksumTable[(result & 0xFF) ^ (byte)current] ^ (result >> 8);
|
||||||
|
|
||||||
|
byte[] hash = BitConverter.GetBytes(~result);
|
||||||
|
Array.Reverse(hash);
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] ComputeHash(byte[] data)
|
||||||
|
{
|
||||||
|
using (MemoryStream stream = new MemoryStream(data))
|
||||||
|
return ComputeHash(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string HashToString(byte[] data)
|
||||||
|
{
|
||||||
|
var hash = this.ComputeHash(data);
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (int i = 0; i < hash.Length; i++)
|
||||||
|
{
|
||||||
|
sb.Append(hash[i].ToString("X2"));
|
||||||
|
}
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
50
AppLibs/AppLibs/Libs/Crypt/CRC64.cs
Normal file
50
AppLibs/AppLibs/Libs/Crypt/CRC64.cs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace AppLibs.Libs.Crypt
|
||||||
|
{
|
||||||
|
public class CRC64
|
||||||
|
{
|
||||||
|
private const ulong Polynomial = 0xC96C5795D7870F42;
|
||||||
|
private readonly ulong[] _table = new ulong[256];
|
||||||
|
|
||||||
|
public CRC64()
|
||||||
|
{
|
||||||
|
for (ulong i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
ulong crc = i;
|
||||||
|
for (int j = 0; j < 8; j++)
|
||||||
|
{
|
||||||
|
if ((crc & 1) == 1)
|
||||||
|
{
|
||||||
|
crc = (crc >> 1) ^ Polynomial;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
crc >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_table[i] = crc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ulong ComputeHash(byte[] buffer)
|
||||||
|
{
|
||||||
|
ulong crc = 0xFFFFFFFFFFFFFFFF;
|
||||||
|
foreach (byte b in buffer)
|
||||||
|
{
|
||||||
|
byte tableIndex = (byte)((crc ^ b) & 0xFF);
|
||||||
|
crc = _table[tableIndex] ^ (crc >> 8);
|
||||||
|
}
|
||||||
|
return ~crc;
|
||||||
|
}
|
||||||
|
public string HashToString(byte[] data)
|
||||||
|
{
|
||||||
|
var hash = this.ComputeHash(data);
|
||||||
|
return hash.ToString("X2");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
56
AppLibs/AppLibs/Libs/LayoutAttribute.cs
Normal file
56
AppLibs/AppLibs/Libs/LayoutAttribute.cs
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
|
|
||||||
|
namespace AppLibs.Libs
|
||||||
|
{
|
||||||
|
public enum LayoutOptions
|
||||||
|
{
|
||||||
|
Default,
|
||||||
|
None,
|
||||||
|
Custom
|
||||||
|
}
|
||||||
|
public class LayoutAttribute : Attribute, IActionFilter
|
||||||
|
{
|
||||||
|
|
||||||
|
private string _layoutName;
|
||||||
|
|
||||||
|
public LayoutAttribute():this(LayoutOptions.Default)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public LayoutAttribute(LayoutOptions option, string layoutName = "")
|
||||||
|
{
|
||||||
|
switch (option)
|
||||||
|
{
|
||||||
|
case LayoutOptions.Default:
|
||||||
|
_layoutName = "Async";
|
||||||
|
break;
|
||||||
|
case LayoutOptions.Custom:
|
||||||
|
_layoutName = layoutName;
|
||||||
|
break;
|
||||||
|
case LayoutOptions.None:
|
||||||
|
_layoutName = "None";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IActionFilter.OnActionExecuted(ActionExecutedContext context)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void IActionFilter.OnActionExecuting(ActionExecutingContext context)
|
||||||
|
{
|
||||||
|
Controller? controller = context.Controller as Controller;
|
||||||
|
if (controller != null)
|
||||||
|
{
|
||||||
|
controller.ViewData["LayoutName"] = this._layoutName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
61
AppLibs/AppLibs/Libs/NavItem.cs
Normal file
61
AppLibs/AppLibs/Libs/NavItem.cs
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
using Microsoft.AspNetCore.Html;
|
||||||
|
using Microsoft.Extensions.Logging.Console;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace AppLibs.Libs
|
||||||
|
{
|
||||||
|
public class NavItem
|
||||||
|
{
|
||||||
|
[JsonProperty(PropertyName = "id")]
|
||||||
|
public string ID { set; get; }
|
||||||
|
|
||||||
|
[JsonProperty(PropertyName = "name")]
|
||||||
|
public string Name { set; get; }
|
||||||
|
|
||||||
|
[JsonProperty(PropertyName = "group")]
|
||||||
|
public bool IsGroup { set; get; }
|
||||||
|
|
||||||
|
[JsonProperty(PropertyName = "icon")]
|
||||||
|
public string Icon { set; get; }
|
||||||
|
|
||||||
|
[JsonProperty(PropertyName = "url")]
|
||||||
|
public string Url { set; get; }
|
||||||
|
|
||||||
|
[JsonProperty(PropertyName = "flexpage")]
|
||||||
|
public bool? IsFlexPage { set; get; }
|
||||||
|
|
||||||
|
[JsonProperty(PropertyName = "sub-item")]
|
||||||
|
public List<NavItem> SubItem { set; get; }
|
||||||
|
|
||||||
|
public NavItem()
|
||||||
|
{
|
||||||
|
Icon = "";
|
||||||
|
ID = "";
|
||||||
|
Name = "";
|
||||||
|
IsGroup = false;
|
||||||
|
IsFlexPage = false;
|
||||||
|
Url = "";
|
||||||
|
SubItem = new List<NavItem>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IHtmlContent ToFlexPageAttribute()
|
||||||
|
{
|
||||||
|
Console.WriteLine(IsFlexPage.ToString());
|
||||||
|
if (IsFlexPage.HasValue && IsFlexPage.Value)
|
||||||
|
{
|
||||||
|
|
||||||
|
return new HtmlString("IsFlexPage");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new HtmlString("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
38
AppLibs/AppLibs/Libs/PageInforAttribute.cs
Normal file
38
AppLibs/AppLibs/Libs/PageInforAttribute.cs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
|
|
||||||
|
namespace AppLibs.Libs
|
||||||
|
{
|
||||||
|
public class PageInforAttribute : Attribute, IActionFilter
|
||||||
|
{
|
||||||
|
private string _pageID;
|
||||||
|
private string _pageName;
|
||||||
|
private string _flexPage;
|
||||||
|
|
||||||
|
public PageInforAttribute(string pageID, string pageName)
|
||||||
|
{
|
||||||
|
this._pageID = pageID;
|
||||||
|
this._pageName = pageName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PageInforAttribute(string pageID, string pageName, string flexPage) : this(pageID, pageName)
|
||||||
|
{
|
||||||
|
this._flexPage = flexPage;
|
||||||
|
|
||||||
|
}
|
||||||
|
public void OnActionExecuted(ActionExecutedContext context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnActionExecuting(ActionExecutingContext context)
|
||||||
|
{
|
||||||
|
Controller? controller = context.Controller as Controller;
|
||||||
|
if (controller != null)
|
||||||
|
{
|
||||||
|
controller.ViewData["PageID"] = this._pageID;
|
||||||
|
controller.ViewData["Title"] = this._pageName;
|
||||||
|
controller.ViewData["FlexPage"] = this._flexPage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
20
AppLibs/AppLibs/Libs/Pages/APage.cs
Normal file
20
AppLibs/AppLibs/Libs/Pages/APage.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace AppLibs.Libs.Pages
|
||||||
|
{
|
||||||
|
public class APage: APageLayout
|
||||||
|
{
|
||||||
|
public string Title { get; set; } = "";
|
||||||
|
|
||||||
|
public string LayoutName { set; get; }
|
||||||
|
public string PageId { set; get; } = "";
|
||||||
|
|
||||||
|
public string FlexPageId { set; get; } = "None";
|
||||||
|
|
||||||
|
public override string PageType { get { return "Page"; } }
|
||||||
|
}
|
||||||
|
}
|
23
AppLibs/AppLibs/Libs/Pages/APageLayout.cs
Normal file
23
AppLibs/AppLibs/Libs/Pages/APageLayout.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace AppLibs.Libs.Pages
|
||||||
|
{
|
||||||
|
public class APageLayout : IPage
|
||||||
|
{
|
||||||
|
public virtual string PageType { get { return "LayoutPage"; } }
|
||||||
|
|
||||||
|
public string Content { get; set; } = "";
|
||||||
|
public string Scripts { get; set; } = "";
|
||||||
|
|
||||||
|
public IActionResult Json()
|
||||||
|
{
|
||||||
|
return new ContentResult() { Content = JsonConvert.SerializeObject(this), ContentType = "application/json" };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
17
AppLibs/AppLibs/Libs/Pages/IPage.cs
Normal file
17
AppLibs/AppLibs/Libs/Pages/IPage.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace AppLibs.Libs.Pages
|
||||||
|
{
|
||||||
|
public interface IPage
|
||||||
|
{
|
||||||
|
public string PageType { get; }
|
||||||
|
public string Content { set; get; }
|
||||||
|
public string Scripts { set; get; }
|
||||||
|
public IActionResult Json();
|
||||||
|
}
|
||||||
|
}
|
55
AppLibs/AppLibs/Libs/WSNavigation.cs
Normal file
55
AppLibs/AppLibs/Libs/WSNavigation.cs
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace AppLibs.Libs
|
||||||
|
{
|
||||||
|
public class WSNavigation
|
||||||
|
{
|
||||||
|
private static List<NavItem> list = new List<NavItem>() ;
|
||||||
|
private static readonly object loadLock = new object();
|
||||||
|
private static Task? t;
|
||||||
|
|
||||||
|
public static async Task LoadJson()
|
||||||
|
{
|
||||||
|
lock (loadLock)
|
||||||
|
{
|
||||||
|
// Nếu đang có task load cũ chưa xong, có thể đợi hoặc hủy (tùy logic)
|
||||||
|
if (t != null && !t.IsCompleted)
|
||||||
|
return;
|
||||||
|
|
||||||
|
t = LoadNavItem();
|
||||||
|
}
|
||||||
|
await t.ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static async Task LoadNavItem()
|
||||||
|
{
|
||||||
|
var newList = new List<NavItem>();
|
||||||
|
using (var reader = new StreamReader(Path.GetFullPath("Json/navlist.json")))
|
||||||
|
{
|
||||||
|
string json = await reader.ReadToEndAsync().ConfigureAwait(false);
|
||||||
|
var deserializedList = JsonConvert.DeserializeObject<List<NavItem>>(json);
|
||||||
|
if (deserializedList != null)
|
||||||
|
{
|
||||||
|
newList = deserializedList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.Threading.Interlocked.Exchange(ref list, newList);
|
||||||
|
}
|
||||||
|
public static async Task<List<NavItem>> GetListMenu()
|
||||||
|
{
|
||||||
|
if (t != null)
|
||||||
|
{
|
||||||
|
if (!t.IsCompleted)
|
||||||
|
{
|
||||||
|
await t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
253
AppLibs/AppLibs/wwwroot/css/atg-font/atg-admin-font.css
Normal file
253
AppLibs/AppLibs/wwwroot/css/atg-font/atg-admin-font.css
Normal file
@ -0,0 +1,253 @@
|
|||||||
|
@font-face {
|
||||||
|
font-family: 'atg-admin-font';
|
||||||
|
font-style: normal;
|
||||||
|
font-display: block;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url("../../font/atgfont-Regular.woff") format('woff'), url("../../font/atgfont-Regular.woff2") format('woff2')
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg {
|
||||||
|
font-family: atg-admin-font;
|
||||||
|
font-weight: 400;
|
||||||
|
text-rendering: auto;
|
||||||
|
color: inherit;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-1x {
|
||||||
|
font-size: 1em
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-2x {
|
||||||
|
font-size: 2em
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-3x {
|
||||||
|
font-size: 3em
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-4x {
|
||||||
|
font-size: 4em
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-5x {
|
||||||
|
font-size: 5em
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-6x {
|
||||||
|
font-size: 6em
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-7x {
|
||||||
|
font-size: 7em
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-8x {
|
||||||
|
font-size: 8em
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-9x {
|
||||||
|
font-size: 9em
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-10x {
|
||||||
|
font-size: 10em
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-message:before {
|
||||||
|
content: "\a001"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-email:before {
|
||||||
|
content: "\a002"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-check-sqare:before {
|
||||||
|
content: "\a003"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-calendar:before {
|
||||||
|
content: "\a004"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-notification:before {
|
||||||
|
content: "\a005"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-search:before {
|
||||||
|
content: "\a006"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-star:before {
|
||||||
|
content: "\a007"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-setting:before {
|
||||||
|
content: "\a008"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-user:before {
|
||||||
|
content: "\a009"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-user-1:before {
|
||||||
|
content: "\a00a"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-package:before {
|
||||||
|
content: "\a00b"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-print:before {
|
||||||
|
content: "\a00c"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-layout:before {
|
||||||
|
content: "\a00d"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-grid:before {
|
||||||
|
content: "\a00e"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-grid:before {
|
||||||
|
content: "\a00e"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-document:before {
|
||||||
|
content: "\a00f"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-instagram:before {
|
||||||
|
content: "\a010"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-tweeter:before {
|
||||||
|
content: "\a011"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-facebook:before {
|
||||||
|
content: "\a012"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-google-plus:before {
|
||||||
|
content: "\a013"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-phone:before {
|
||||||
|
content: "\a014"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-location:before {
|
||||||
|
content: "\a015"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-heart:before {
|
||||||
|
content: "\a016"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-more:before {
|
||||||
|
content: "\a017"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-home:before{
|
||||||
|
content: "\a018"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-circle:before{
|
||||||
|
content: "\a019"
|
||||||
|
}
|
||||||
|
.atg-down:before {
|
||||||
|
content: "\a01a"
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-down-thick:before {
|
||||||
|
content: "\a01a"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-x:before {
|
||||||
|
content: "\a01b"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-book:before {
|
||||||
|
content: "\a01c"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-catalogue:before {
|
||||||
|
content: "\a01d"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-product:before{
|
||||||
|
content: "\a01e"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-plus:before{
|
||||||
|
content: "\a01f"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-embeded:before {
|
||||||
|
content: "\a020"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-upload:before {
|
||||||
|
content: "\a021"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-download:before {
|
||||||
|
content: "\a022"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-moveto:before {
|
||||||
|
content: "\a023"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.atg-copy:before {
|
||||||
|
content: "\a024"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.atg-pencil:before {
|
||||||
|
content: "\a025"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.atg-rename:before {
|
||||||
|
content: "\a026"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-delete:before {
|
||||||
|
content: "\a027"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-menu:before {
|
||||||
|
content: "\a029"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-dot:before {
|
||||||
|
content: "\a02a"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-storage:before {
|
||||||
|
content: "\a02b"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-storage-setting:before {
|
||||||
|
content: "\a02c"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-storage-add:before {
|
||||||
|
content: "\a02d"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-tick:before{
|
||||||
|
content: "\a02e"
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg-less:before{
|
||||||
|
content: "\a02f"
|
||||||
|
}
|
||||||
|
.atg-minus:before {
|
||||||
|
content: "\a031"
|
||||||
|
}
|
195
AppLibs/AppLibs/wwwroot/css/atg-font/atg-font.css
Normal file
195
AppLibs/AppLibs/wwwroot/css/atg-font/atg-font.css
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
@font-face {
|
||||||
|
font-family: 'ATG-Icon';
|
||||||
|
font-display: block;
|
||||||
|
src: url("../../font/ATGIcon-Regular.woff") format('woff')/*, url("../font/atg-admin-font.woff2") format('woff2')*/
|
||||||
|
}
|
||||||
|
|
||||||
|
.atg {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-family: ATG-Icon;
|
||||||
|
font-weight: 400;
|
||||||
|
text-rendering: auto;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
font-style: normal;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-1x {
|
||||||
|
font-size: 1em
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-2x {
|
||||||
|
font-size: 2em
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-3x {
|
||||||
|
font-size: 3em
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-4x {
|
||||||
|
font-size: 4em
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-5x {
|
||||||
|
font-size: 5em
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-6x {
|
||||||
|
font-size: 6em
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-7x {
|
||||||
|
font-size: 7em
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-8x {
|
||||||
|
font-size: 8em
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-9x {
|
||||||
|
font-size: 9em
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-10x {
|
||||||
|
font-size: 10em
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-s-lightbulb-gear:before{
|
||||||
|
content: '\effff'
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-lightbulb-gear:before{
|
||||||
|
content: '\f0001'
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-target:before{
|
||||||
|
content: '\f0002'
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-stragery:before{
|
||||||
|
content: '\f0003'
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-focus:before{
|
||||||
|
content: '\f0004'
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-cup:before{
|
||||||
|
content: '\f0005'
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-handshake:before{
|
||||||
|
content: '\f0006'
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-clock:before {
|
||||||
|
content: '\f0007'
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-clock-thin::before {
|
||||||
|
content: '\f0008'
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-phone:before {
|
||||||
|
content: '\f0009'
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-phone1:before {
|
||||||
|
content: '\f000a'
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-less:before {
|
||||||
|
content: '\f000B'
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-more:before {
|
||||||
|
content: '\f000C'
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-up:before {
|
||||||
|
content: '\f000D'
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-down:before {
|
||||||
|
content: '\f000E'
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-down-thick:before {
|
||||||
|
content: '\f000F'
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-less-thick:before {
|
||||||
|
content: '\f0010'
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-more-thick:before {
|
||||||
|
content: '\f0011'
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-up-thick:before {
|
||||||
|
content: '\f0012'
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-shape-down:before {
|
||||||
|
content: '\f0013'
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-shape-less:before {
|
||||||
|
content: '\f0014'
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-shape-more:before {
|
||||||
|
content: '\f0015'
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-shape-up:before {
|
||||||
|
content: '\f0016'
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-arrow-right-thick:before {
|
||||||
|
content: '\f0017'
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-arrow-right-thin:before {
|
||||||
|
content: '\f0018'
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-location1:before {
|
||||||
|
content: '\f0019'
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-location2:before{
|
||||||
|
content: '\f0020'
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-email1:before{
|
||||||
|
content: '\f0021'
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-email2:before {
|
||||||
|
content: '\f0022'
|
||||||
|
}
|
||||||
|
.a-twitter:before {
|
||||||
|
content: '\f0023'
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-google-plus:before {
|
||||||
|
content: '\f0024'
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-facebook:before {
|
||||||
|
content: '\f0025'
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-linkedin:before {
|
||||||
|
content: '\f0026'
|
||||||
|
}
|
||||||
|
.a-youtube:before {
|
||||||
|
content: '\f0027'
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-bag:before {
|
||||||
|
content: '\f0028'
|
||||||
|
}
|
1
AppLibs/AppLibs/wwwroot/css/atg-lib/atg-core-min.css
vendored
Normal file
1
AppLibs/AppLibs/wwwroot/css/atg-lib/atg-core-min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
2820
AppLibs/AppLibs/wwwroot/css/atg-lib/atg-core.css
Normal file
2820
AppLibs/AppLibs/wwwroot/css/atg-lib/atg-core.css
Normal file
File diff suppressed because it is too large
Load Diff
498
AppLibs/AppLibs/wwwroot/css/atg-lib/atg-upload.css
Normal file
498
AppLibs/AppLibs/wwwroot/css/atg-lib/atg-upload.css
Normal file
@ -0,0 +1,498 @@
|
|||||||
|
.u-overlay{
|
||||||
|
position:absolute;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
z-index: 10000;
|
||||||
|
background: rgba(0,0,0, .2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-scroll {
|
||||||
|
overflow: hidden;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@media (min-width: 768px){
|
||||||
|
.nav-tupload .item .name {
|
||||||
|
display:block!important
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 996px){
|
||||||
|
.breadcrumb {
|
||||||
|
width: 60% !important
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-height: 800px) {
|
||||||
|
.u-container {
|
||||||
|
height: 100vh!important
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-wrapper {
|
||||||
|
margin: 0 !important;
|
||||||
|
height: 80vh !important
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-container {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-n-wrapper {
|
||||||
|
box-shadow: 0 0 10px 0 rgb(0 0 0 / 15%);
|
||||||
|
width: 100%;
|
||||||
|
height: 800px;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 5px
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-wrapper {
|
||||||
|
border-radius: 5px;
|
||||||
|
overflow:hidden;
|
||||||
|
height: 800px;
|
||||||
|
width: 80vw;
|
||||||
|
margin: 150px 0;
|
||||||
|
background-color: #fff;
|
||||||
|
box-shadow: 0 4px 8px 0 rgb(0 0 0 / 20%), 0 6px 20px 0 rgb(0 0 0 / 19%);
|
||||||
|
transition: all 0.35s ease-in-out
|
||||||
|
}
|
||||||
|
|
||||||
|
.container-tupload {
|
||||||
|
width: 100%;
|
||||||
|
background: #fff;
|
||||||
|
border-bottom: 1px solid #edebe9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-tupload .item{
|
||||||
|
padding: 12px 10px;
|
||||||
|
transition: all .3s ease-in-out
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-tupload .item span{
|
||||||
|
color: #333;
|
||||||
|
line-height: 22px;
|
||||||
|
}
|
||||||
|
.nav-tupload .item .name {
|
||||||
|
display: none
|
||||||
|
}
|
||||||
|
.nav-tupload .item .atg{
|
||||||
|
color: #154ab9
|
||||||
|
}
|
||||||
|
.nav-tupload .item .atg:last-child {
|
||||||
|
color: #232323 !important
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-tupload .item:hover{
|
||||||
|
background-color: rgb(243, 242, 241)
|
||||||
|
}
|
||||||
|
[data-dropdown] .sub-item {
|
||||||
|
border-radius: 5px;
|
||||||
|
overflow: hidden;
|
||||||
|
position: fixed;
|
||||||
|
background: #fff;
|
||||||
|
width: 180px;
|
||||||
|
z-index: 10001;
|
||||||
|
box-shadow: 0 4px 8px 0 rgb(0 0 0 / 20%), 0 6px 20px 0 rgb(0 0 0 / 19%);
|
||||||
|
height: 0;
|
||||||
|
transition: height 0.3s ease-out
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-dropdown] .sub-item.show {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
[data-dropdown].active > .dropdown {
|
||||||
|
background: rgb(222 222 222)
|
||||||
|
}
|
||||||
|
[data-dropdown] .sub-item .item {
|
||||||
|
transition: .3s all ease-in-out;
|
||||||
|
padding: 10px 15px;
|
||||||
|
color: #333
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-dropdown] .sub-item .item:hover {
|
||||||
|
background-color: rgb(243, 242, 241)
|
||||||
|
}
|
||||||
|
|
||||||
|
.bt-close {
|
||||||
|
padding: 12px 25px;
|
||||||
|
background: #7367f0;
|
||||||
|
color: #fff;
|
||||||
|
transition: .3s all ease-in-out
|
||||||
|
}
|
||||||
|
|
||||||
|
.bt-close:hover {
|
||||||
|
background: #8d1a1e
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-c-file{
|
||||||
|
height: calc(100% - 54px);
|
||||||
|
width: 100%;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-row{
|
||||||
|
width: 100%;
|
||||||
|
padding: 25px 25px 0 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.breadcrumb{
|
||||||
|
width: 80%
|
||||||
|
}
|
||||||
|
|
||||||
|
.breadcrumb .dropdown,
|
||||||
|
.breadcrumb .item,
|
||||||
|
.breadcrumb .sep {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
padding: 5px 8px;
|
||||||
|
color: #333;
|
||||||
|
transition: .3s all ease-in-out;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.breadcrumb .item.ellipsis {
|
||||||
|
max-width: 160px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.breadcrumb .item:hover {
|
||||||
|
background: #f3f2f1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.breadcrumb > .item:last-child{
|
||||||
|
font-weight: 600;
|
||||||
|
cursor: default !important;
|
||||||
|
background: #fff !important;
|
||||||
|
text-overflow: inherit !important;
|
||||||
|
max-width: max-content !important;
|
||||||
|
overflow: visible !important
|
||||||
|
}
|
||||||
|
|
||||||
|
.breadcrumb > .citem[data-dropdown] > .sub-item{
|
||||||
|
top: 28px;
|
||||||
|
min-width: 160px !important
|
||||||
|
}
|
||||||
|
.breadcrumb > .citem[data-dropdown] > .sub-item > .item {
|
||||||
|
padding:10px;
|
||||||
|
font-size: .8rem
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal {
|
||||||
|
visibility: hidden;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 0;
|
||||||
|
overflow: auto;
|
||||||
|
opacity: 1;
|
||||||
|
background-color: rgba(0,0,0,0.2);
|
||||||
|
transition: all 0.25s ease-in-out
|
||||||
|
}
|
||||||
|
.modal.show {
|
||||||
|
visibility: visible;
|
||||||
|
opacity: 1;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-content {
|
||||||
|
border-radius: 5px;
|
||||||
|
overflow: hidden;
|
||||||
|
visibility: hidden;
|
||||||
|
height: 0;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 25px;
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid #edebe9;
|
||||||
|
width: 80%;
|
||||||
|
box-shadow: 0 4px 8px 0 rgb(0 0 0 / 20%), 0 6px 20px 0 rgb(0 0 0 / 19%);
|
||||||
|
transition: height 0.3s ease-in-out
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.modal-content.show{
|
||||||
|
visibility: visible;
|
||||||
|
height: auto
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid-folder > .grid-sizer,
|
||||||
|
.grid-folder > .grid-item,
|
||||||
|
.grid-file > .grid-sizer,
|
||||||
|
.grid-file > .grid-item{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid-folder > .grid-item {
|
||||||
|
padding: 15px 5px
|
||||||
|
}
|
||||||
|
.grid-file > .grid-item {
|
||||||
|
padding: 6px
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width:300px) {
|
||||||
|
.grid-folder > .grid-sizer,
|
||||||
|
.grid-folder > .grid-item,
|
||||||
|
.grid-file > .grid-sizer,
|
||||||
|
.grid-file > .grid-item {
|
||||||
|
width: 50% !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width:600px) {
|
||||||
|
.grid-folder > .grid-sizer,
|
||||||
|
.grid-folder > .grid-item,
|
||||||
|
.grid-file > .grid-sizer,
|
||||||
|
.grid-file > .grid-item {
|
||||||
|
width: 33.33% !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width:992px) {
|
||||||
|
.grid-folder > .grid-sizer,
|
||||||
|
.grid-folder > .grid-item,
|
||||||
|
.grid-file > .grid-sizer,
|
||||||
|
.grid-file > .grid-item {
|
||||||
|
width: 25% !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1400px){
|
||||||
|
.grid-folder > .grid-sizer,
|
||||||
|
.grid-folder > .grid-item,
|
||||||
|
.grid-file > .grid-sizer,
|
||||||
|
.grid-file > .grid-item {
|
||||||
|
width: 16.66% !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (min-width: 1920px) {
|
||||||
|
.grid-folder > .grid-sizer,
|
||||||
|
.grid-folder > .grid-item,
|
||||||
|
.grid-file > .grid-sizer,
|
||||||
|
.grid-file > .grid-item {
|
||||||
|
width: 12.56% !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.conFile {
|
||||||
|
position: relative;
|
||||||
|
padding: 4px;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 5px;
|
||||||
|
-webkit-box-shadow: 0 1px 3px 1px rgb(1 1 0 / 5%);
|
||||||
|
box-shadow: 0 1px 3px 1px rgb(1 1 0 / 5%);
|
||||||
|
transition: all .3s ease-in-out;
|
||||||
|
cursor:pointer
|
||||||
|
}
|
||||||
|
|
||||||
|
.conFile:hover{
|
||||||
|
border: solid 1px rgba(0,0,0, .15)
|
||||||
|
}
|
||||||
|
|
||||||
|
.imagePreview {
|
||||||
|
overflow: hidden;
|
||||||
|
transition: all .3s ease-in-out;
|
||||||
|
border-radius: 5px
|
||||||
|
}
|
||||||
|
|
||||||
|
.conFile img, .imagePreview {
|
||||||
|
width: 100%
|
||||||
|
}
|
||||||
|
|
||||||
|
.conFolder{
|
||||||
|
padding-top: 15px;
|
||||||
|
transition: background .3s ease-in-out
|
||||||
|
}
|
||||||
|
|
||||||
|
.conFolder:hover {
|
||||||
|
background: #F3F2F1
|
||||||
|
}
|
||||||
|
|
||||||
|
.conFolder:hover .btCon, .btCon:hover, .conFolder.active .btCon {
|
||||||
|
display: flex
|
||||||
|
}
|
||||||
|
|
||||||
|
.conFolder.active {
|
||||||
|
background: #EDEBE9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.conFolder.active .btSelect{
|
||||||
|
background:#7367f0;
|
||||||
|
border: 1px solid #fff;
|
||||||
|
}
|
||||||
|
.btCon:hover .atg {
|
||||||
|
display:block;
|
||||||
|
color: #333
|
||||||
|
}
|
||||||
|
|
||||||
|
.conFolder.active .atg{
|
||||||
|
display: block;
|
||||||
|
color: #fff
|
||||||
|
}
|
||||||
|
|
||||||
|
.folder-front {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.have-file {
|
||||||
|
box-shadow: 0 1px 3px 2px rgb(1 1 0 / 20%);
|
||||||
|
position: absolute;
|
||||||
|
top: 12%;
|
||||||
|
left: 5%;
|
||||||
|
right: 5%;
|
||||||
|
bottom: 10%;
|
||||||
|
background-color: white;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.btCon {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
width: 35px;
|
||||||
|
height: 35px;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
z-index:2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btSelect{
|
||||||
|
border: #333 1px solid;
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btSelect .atg{
|
||||||
|
display: none;
|
||||||
|
font-size: 9px
|
||||||
|
}
|
||||||
|
|
||||||
|
.folder {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10% 15% 0 15%;
|
||||||
|
cursor:default
|
||||||
|
}
|
||||||
|
.conImg, .conImg img{
|
||||||
|
width: 100%
|
||||||
|
}
|
||||||
|
|
||||||
|
.conImg, .folderName{
|
||||||
|
cursor: pointer
|
||||||
|
}
|
||||||
|
|
||||||
|
.numF{
|
||||||
|
color:#eeeeee;
|
||||||
|
font-size: .8rem;
|
||||||
|
position:absolute;
|
||||||
|
bottom: 8%;
|
||||||
|
left: 8%;
|
||||||
|
z-index: 4
|
||||||
|
}
|
||||||
|
|
||||||
|
.folderName {
|
||||||
|
margin-top: 20px;
|
||||||
|
margin-bottom: 10%;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
max-width: 95%;
|
||||||
|
text-align: center;
|
||||||
|
font-size: .8rem
|
||||||
|
}
|
||||||
|
|
||||||
|
.con-slide-upload {
|
||||||
|
position: absolute;
|
||||||
|
background: #fff;
|
||||||
|
right: -350px;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: 300px;
|
||||||
|
z-index: 15;
|
||||||
|
max-width: 100%;
|
||||||
|
box-shadow: 0 0 10px 0 rgb(0 0 0 / 15%);
|
||||||
|
transition: right .3s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.con-slide-upload.show{
|
||||||
|
right: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-upload{
|
||||||
|
padding-bottom: 25px
|
||||||
|
}
|
||||||
|
|
||||||
|
.c-slide-header {
|
||||||
|
margin: 24px 20px
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-upload .sl-close {
|
||||||
|
color: #201f1e;
|
||||||
|
font-size: 1rem;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 5px 10px;
|
||||||
|
transition: all .3s ease-in-out
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-upload .sl-close:hover {
|
||||||
|
background-color: #edebe9
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-upload .header{
|
||||||
|
margin: 34px 20px 20px
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-slide-upload{
|
||||||
|
width: 100%;
|
||||||
|
height: calc(100% - 139px);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.scroll-slide-upload .scroll-content{
|
||||||
|
padding: 0 20px
|
||||||
|
}
|
||||||
|
.scroll-slide-upload .item:not(:first-child){
|
||||||
|
margin-top: 20px
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-infor {
|
||||||
|
font-size: .75rem;
|
||||||
|
color: #17a2b8
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-infor.ellipsis{
|
||||||
|
max-width: 170px
|
||||||
|
}
|
||||||
|
|
||||||
|
.c-text .atg {
|
||||||
|
font-size: 1rem;
|
||||||
|
color: #919899
|
||||||
|
}
|
||||||
|
|
||||||
|
.c-progress {
|
||||||
|
height: 2px;
|
||||||
|
position: relative;
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.c-progress .value {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
transition: width 200ms cubic-bezier(.1,.9,.2,1);
|
||||||
|
transition: background-color .35s ease-in;
|
||||||
|
left: 0;
|
||||||
|
background-color: #0078d4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upl-des {
|
||||||
|
font-size: .72rem;
|
||||||
|
color: #919899
|
||||||
|
}
|
778
AppLibs/AppLibs/wwwroot/css/atg-lib/datepicker.css
Normal file
778
AppLibs/AppLibs/wwwroot/css/atg-lib/datepicker.css
Normal file
@ -0,0 +1,778 @@
|
|||||||
|
.air-datepicker-cell.-year-.-other-decade-, .air-datepicker-cell.-day-.-other-month- {
|
||||||
|
color: var(--adp-color-other-month)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-cell.-year-.-other-decade-:hover, .air-datepicker-cell.-day-.-other-month-:hover {
|
||||||
|
color: var(--adp-color-other-month-hover)
|
||||||
|
}
|
||||||
|
|
||||||
|
.-disabled-.-focus-.air-datepicker-cell.-year-.-other-decade-, .-disabled-.-focus-.air-datepicker-cell.-day-.-other-month- {
|
||||||
|
color: var(--adp-color-other-month)
|
||||||
|
}
|
||||||
|
|
||||||
|
.-selected-.air-datepicker-cell.-year-.-other-decade-, .-selected-.air-datepicker-cell.-day-.-other-month- {
|
||||||
|
color: #fff;
|
||||||
|
background: var(--adp-background-color-selected-other-month)
|
||||||
|
}
|
||||||
|
|
||||||
|
.-selected-.-focus-.air-datepicker-cell.-year-.-other-decade-, .-selected-.-focus-.air-datepicker-cell.-day-.-other-month- {
|
||||||
|
background: var(--adp-background-color-selected-other-month-focused)
|
||||||
|
}
|
||||||
|
|
||||||
|
.-in-range-.air-datepicker-cell.-year-.-other-decade-, .-in-range-.air-datepicker-cell.-day-.-other-month- {
|
||||||
|
background-color: var(--adp-background-color-in-range);
|
||||||
|
color: var(--adp-color)
|
||||||
|
}
|
||||||
|
|
||||||
|
.-in-range-.-focus-.air-datepicker-cell.-year-.-other-decade-, .-in-range-.-focus-.air-datepicker-cell.-day-.-other-month- {
|
||||||
|
background-color: var(--adp-background-color-in-range-focused)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-cell.-year-.-other-decade-:empty, .air-datepicker-cell.-day-.-other-month-:empty {
|
||||||
|
background: none;
|
||||||
|
border: none
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-cell {
|
||||||
|
border-radius: var(--adp-cell-border-radius);
|
||||||
|
box-sizing: border-box;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
position: relative;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
z-index: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-cell.-focus- {
|
||||||
|
background: var(--adp-cell-background-color-hover)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-cell.-current- {
|
||||||
|
color: var(--adp-color-current-date)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-cell.-current-.-focus- {
|
||||||
|
color: var(--adp-color)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-cell.-current-.-in-range- {
|
||||||
|
color: var(--adp-color-current-date)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-cell.-disabled- {
|
||||||
|
cursor: default;
|
||||||
|
color: var(--adp-color-disabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-cell.-disabled-.-focus- {
|
||||||
|
color: var(--adp-color-disabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-cell.-disabled-.-in-range- {
|
||||||
|
color: var(--adp-color-disabled-in-range)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-cell.-disabled-.-current-.-focus- {
|
||||||
|
color: var(--adp-color-disabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-cell.-in-range- {
|
||||||
|
background: var(--adp-cell-background-color-in-range);
|
||||||
|
border-radius: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-cell.-in-range-:hover {
|
||||||
|
background: var(--adp-cell-background-color-in-range-hover)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-cell.-range-from- {
|
||||||
|
border: 1px solid var(--adp-cell-border-color-in-range);
|
||||||
|
background-color: var(--adp-cell-background-color-in-range);
|
||||||
|
border-radius: var(--adp-cell-border-radius) 0 0 var(--adp-cell-border-radius)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-cell.-range-to- {
|
||||||
|
border: 1px solid var(--adp-cell-border-color-in-range);
|
||||||
|
background-color: var(--adp-cell-background-color-in-range);
|
||||||
|
border-radius: 0 var(--adp-cell-border-radius) var(--adp-cell-border-radius) 0
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-cell.-range-to-.-range-from- {
|
||||||
|
border-radius: var(--adp-cell-border-radius)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-cell.-selected- {
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
background: var(--adp-cell-background-color-selected)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-cell.-selected-.-current- {
|
||||||
|
color: #fff;
|
||||||
|
background: var(--adp-cell-background-color-selected)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-cell.-selected-.-focus- {
|
||||||
|
background: var(--adp-cell-background-color-selected-hover)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-body {
|
||||||
|
transition: all var(--adp-transition-duration) var(--adp-transition-ease)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-body.-hidden- {
|
||||||
|
display: none
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-body--day-names {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(7, var(--adp-day-cell-width));
|
||||||
|
margin: 8px 0 3px
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-body--day-name {
|
||||||
|
color: var(--adp-day-name-color);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex: 1;
|
||||||
|
text-align: center;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-size: .8em
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-body--day-name.-clickable- {
|
||||||
|
cursor: pointer
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-body--day-name.-clickable-:hover {
|
||||||
|
color: var(--adp-day-name-color-hover)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-body--cells {
|
||||||
|
display: grid
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-body--cells.-days- {
|
||||||
|
grid-template-columns: repeat(7, var(--adp-day-cell-width));
|
||||||
|
grid-auto-rows: var(--adp-day-cell-height)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-body--cells.-months- {
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
grid-auto-rows: var(--adp-month-cell-height)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-body--cells.-years- {
|
||||||
|
grid-template-columns: repeat(4, 1fr);
|
||||||
|
grid-auto-rows: var(--adp-year-cell-height)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-nav {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
border-bottom: 1px solid var(--adp-border-color-inner);
|
||||||
|
min-height: var(--adp-nav-height);
|
||||||
|
padding: var(--adp-padding);
|
||||||
|
box-sizing: content-box
|
||||||
|
}
|
||||||
|
|
||||||
|
.-only-timepicker- .air-datepicker-nav {
|
||||||
|
display: none
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-nav--title, .air-datepicker-nav--action {
|
||||||
|
display: flex;
|
||||||
|
cursor: pointer;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-nav--action {
|
||||||
|
width: var(--adp-nav-action-size);
|
||||||
|
border-radius: var(--adp-border-radius);
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
user-select: none
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-nav--action:hover {
|
||||||
|
background: var(--adp-background-color-hover)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-nav--action:active {
|
||||||
|
background: var(--adp-background-color-active)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-nav--action.-disabled- {
|
||||||
|
visibility: hidden
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-nav--action svg {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-nav--action path {
|
||||||
|
fill: none;
|
||||||
|
stroke: var(--adp-nav-arrow-color);
|
||||||
|
stroke-width: 2px
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-nav--title {
|
||||||
|
border-radius: var(--adp-border-radius);
|
||||||
|
padding: 0 8px
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-nav--title i {
|
||||||
|
font-style: normal;
|
||||||
|
color: var(--adp-nav-color-secondary);
|
||||||
|
margin-left: .3em
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-nav--title:hover {
|
||||||
|
background: var(--adp-background-color-hover)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-nav--title:active {
|
||||||
|
background: var(--adp-background-color-active)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-nav--title.-disabled- {
|
||||||
|
cursor: default;
|
||||||
|
background: none
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-buttons {
|
||||||
|
display: grid;
|
||||||
|
grid-auto-columns: 1fr;
|
||||||
|
grid-auto-flow: column
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-button {
|
||||||
|
display: inline-flex;
|
||||||
|
color: var(--adp-btn-color);
|
||||||
|
border-radius: var(--adp-btn-border-radius);
|
||||||
|
cursor: pointer;
|
||||||
|
height: var(--adp-btn-height);
|
||||||
|
border: none;
|
||||||
|
background: rgba(255,255,255,0)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-button:hover {
|
||||||
|
color: var(--adp-btn-color-hover);
|
||||||
|
background: var(--adp-btn-background-color-hover)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-button:focus {
|
||||||
|
color: var(--adp-btn-color-hover);
|
||||||
|
background: var(--adp-btn-background-color-hover);
|
||||||
|
outline: none
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-button:active {
|
||||||
|
background: var(--adp-btn-background-color-active)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-button span {
|
||||||
|
outline: none;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-time {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: max-content 1fr;
|
||||||
|
grid-column-gap: 12px;
|
||||||
|
align-items: center;
|
||||||
|
position: relative;
|
||||||
|
padding: 0 var(--adp-time-padding-inner)
|
||||||
|
}
|
||||||
|
|
||||||
|
.-only-timepicker- .air-datepicker-time {
|
||||||
|
border-top: none
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-time--current {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex: 1;
|
||||||
|
font-size: 14px;
|
||||||
|
text-align: center
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-time--current-colon {
|
||||||
|
margin: 0 2px 3px;
|
||||||
|
line-height: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-time--current-hours, .air-datepicker-time--current-minutes {
|
||||||
|
line-height: 1;
|
||||||
|
font-size: 19px;
|
||||||
|
font-family: "Century Gothic",CenturyGothic,AppleGothic,sans-serif;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-time--current-hours:after, .air-datepicker-time--current-minutes:after {
|
||||||
|
content: "";
|
||||||
|
background: var(--adp-background-color-hover);
|
||||||
|
border-radius: var(--adp-border-radius);
|
||||||
|
position: absolute;
|
||||||
|
left: -2px;
|
||||||
|
top: -3px;
|
||||||
|
right: -2px;
|
||||||
|
bottom: -2px;
|
||||||
|
z-index: -1;
|
||||||
|
opacity: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-time--current-hours.-focus-:after, .air-datepicker-time--current-minutes.-focus-:after {
|
||||||
|
opacity: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-time--current-ampm {
|
||||||
|
text-transform: uppercase;
|
||||||
|
align-self: flex-end;
|
||||||
|
color: var(--adp-time-day-period-color);
|
||||||
|
margin-left: 6px;
|
||||||
|
font-size: 11px;
|
||||||
|
margin-bottom: 1px
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-time--row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 11px;
|
||||||
|
height: 17px;
|
||||||
|
background: linear-gradient(to right, var(--adp-time-track-color), var(--adp-time-track-color)) left 50%/100% var(--adp-time-track-height) no-repeat
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-time--row:first-child {
|
||||||
|
margin-bottom: 4px
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-time--row input[type=range] {
|
||||||
|
background: none;
|
||||||
|
cursor: pointer;
|
||||||
|
flex: 1;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
-webkit-appearance: none
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-time--row input[type=range]::-webkit-slider-thumb {
|
||||||
|
-webkit-appearance: none
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-time--row input[type=range]::-ms-tooltip {
|
||||||
|
display: none
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-time--row input[type=range]:hover::-webkit-slider-thumb {
|
||||||
|
border-color: var(--adp-time-track-color-hover)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-time--row input[type=range]:hover::-moz-range-thumb {
|
||||||
|
border-color: var(--adp-time-track-color-hover)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-time--row input[type=range]:hover::-ms-thumb {
|
||||||
|
border-color: var(--adp-time-track-color-hover)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-time--row input[type=range]:focus {
|
||||||
|
outline: none
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-time--row input[type=range]:focus::-webkit-slider-thumb {
|
||||||
|
background: var(--adp-cell-background-color-selected);
|
||||||
|
border-color: var(--adp-cell-background-color-selected)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-time--row input[type=range]:focus::-moz-range-thumb {
|
||||||
|
background: var(--adp-cell-background-color-selected);
|
||||||
|
border-color: var(--adp-cell-background-color-selected)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-time--row input[type=range]:focus::-ms-thumb {
|
||||||
|
background: var(--adp-cell-background-color-selected);
|
||||||
|
border-color: var(--adp-cell-background-color-selected)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-time--row input[type=range]::-webkit-slider-thumb {
|
||||||
|
box-sizing: border-box;
|
||||||
|
height: 12px;
|
||||||
|
width: 12px;
|
||||||
|
border-radius: 3px;
|
||||||
|
border: 1px solid var(--adp-time-track-color);
|
||||||
|
background: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
-webkit-transition: background var(--adp-transition-duration);
|
||||||
|
transition: background var(--adp-transition-duration)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-time--row input[type=range]::-moz-range-thumb {
|
||||||
|
box-sizing: border-box;
|
||||||
|
height: 12px;
|
||||||
|
width: 12px;
|
||||||
|
border-radius: 3px;
|
||||||
|
border: 1px solid var(--adp-time-track-color);
|
||||||
|
background: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
-moz-transition: background var(--adp-transition-duration);
|
||||||
|
transition: background var(--adp-transition-duration)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-time--row input[type=range]::-ms-thumb {
|
||||||
|
box-sizing: border-box;
|
||||||
|
height: 12px;
|
||||||
|
width: 12px;
|
||||||
|
border-radius: 3px;
|
||||||
|
border: 1px solid var(--adp-time-track-color);
|
||||||
|
background: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
-ms-transition: background var(--adp-transition-duration);
|
||||||
|
transition: background var(--adp-transition-duration)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-time--row input[type=range]::-webkit-slider-thumb {
|
||||||
|
margin-top: calc(var(--adp-time-thumb-size)/2*-1)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-time--row input[type=range]::-webkit-slider-runnable-track {
|
||||||
|
border: none;
|
||||||
|
height: var(--adp-time-track-height);
|
||||||
|
cursor: pointer;
|
||||||
|
color: rgba(0,0,0,0);
|
||||||
|
background: rgba(0,0,0,0)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-time--row input[type=range]::-moz-range-track {
|
||||||
|
border: none;
|
||||||
|
height: var(--adp-time-track-height);
|
||||||
|
cursor: pointer;
|
||||||
|
color: rgba(0,0,0,0);
|
||||||
|
background: rgba(0,0,0,0)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-time--row input[type=range]::-ms-track {
|
||||||
|
border: none;
|
||||||
|
height: var(--adp-time-track-height);
|
||||||
|
cursor: pointer;
|
||||||
|
color: rgba(0,0,0,0);
|
||||||
|
background: rgba(0,0,0,0)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-time--row input[type=range]::-ms-fill-lower {
|
||||||
|
background: rgba(0,0,0,0)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-time--row input[type=range]::-ms-fill-upper {
|
||||||
|
background: rgba(0,0,0,0)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker {
|
||||||
|
--adp-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
||||||
|
--adp-font-size: 14px;
|
||||||
|
--adp-width: 246px;
|
||||||
|
--adp-z-index: 100;
|
||||||
|
--adp-padding: 4px;
|
||||||
|
--adp-grid-areas: "nav" "body" "timepicker" "buttons";
|
||||||
|
--adp-transition-duration: .3s;
|
||||||
|
--adp-transition-ease: ease-out;
|
||||||
|
--adp-transition-offset: 8px;
|
||||||
|
--adp-background-color: #fff;
|
||||||
|
--adp-background-color-hover: #f0f0f0;
|
||||||
|
--adp-background-color-active: #eaeaea;
|
||||||
|
--adp-background-color-in-range: rgba(92, 196, 239, .1);
|
||||||
|
--adp-background-color-in-range-focused: rgba(92, 196, 239, .2);
|
||||||
|
--adp-background-color-selected-other-month-focused: #8ad5f4;
|
||||||
|
--adp-background-color-selected-other-month: #a2ddf6;
|
||||||
|
--adp-color: #4a4a4a;
|
||||||
|
--adp-color-secondary: #9c9c9c;
|
||||||
|
--adp-accent-color: #4eb5e6;
|
||||||
|
--adp-color-current-date: var(--adp-accent-color);
|
||||||
|
--adp-color-other-month: #dedede;
|
||||||
|
--adp-color-disabled: #aeaeae;
|
||||||
|
--adp-color-disabled-in-range: #939393;
|
||||||
|
--adp-color-other-month-hover: #c5c5c5;
|
||||||
|
--adp-border-color: #dbdbdb;
|
||||||
|
--adp-border-color-inner: #efefef;
|
||||||
|
--adp-border-radius: 4px;
|
||||||
|
--adp-border-color-inline: #d7d7d7;
|
||||||
|
--adp-nav-height: 32px;
|
||||||
|
--adp-nav-arrow-color: var(--adp-color-secondary);
|
||||||
|
--adp-nav-action-size: 32px;
|
||||||
|
--adp-nav-color-secondary: var(--adp-color-secondary);
|
||||||
|
--adp-day-name-color: #ff9a19;
|
||||||
|
--adp-day-name-color-hover: #8ad5f4;
|
||||||
|
--adp-day-cell-width: 1fr;
|
||||||
|
--adp-day-cell-height: 32px;
|
||||||
|
--adp-month-cell-height: 42px;
|
||||||
|
--adp-year-cell-height: 56px;
|
||||||
|
--adp-pointer-size: 10px;
|
||||||
|
--adp-poiner-border-radius: 2px;
|
||||||
|
--adp-pointer-offset: 14px;
|
||||||
|
--adp-cell-border-radius: 4px;
|
||||||
|
--adp-cell-background-color-hover: var(--adp-background-color-hover);
|
||||||
|
--adp-cell-background-color-selected: #5cc4ef;
|
||||||
|
--adp-cell-background-color-selected-hover: #45bced;
|
||||||
|
--adp-cell-background-color-in-range: rgba(92, 196, 239, 0.1);
|
||||||
|
--adp-cell-background-color-in-range-hover: rgba(92, 196, 239, 0.2);
|
||||||
|
--adp-cell-border-color-in-range: var(--adp-cell-background-color-selected);
|
||||||
|
--adp-btn-height: 32px;
|
||||||
|
--adp-btn-color: var(--adp-accent-color);
|
||||||
|
--adp-btn-color-hover: var(--adp-color);
|
||||||
|
--adp-btn-border-radius: var(--adp-border-radius);
|
||||||
|
--adp-btn-background-color-hover: var(--adp-background-color-hover);
|
||||||
|
--adp-btn-background-color-active: var(--adp-background-color-active);
|
||||||
|
--adp-time-track-height: 1px;
|
||||||
|
--adp-time-track-color: #dedede;
|
||||||
|
--adp-time-track-color-hover: #b1b1b1;
|
||||||
|
--adp-time-thumb-size: 12px;
|
||||||
|
--adp-time-padding-inner: 10px;
|
||||||
|
--adp-time-day-period-color: var(--adp-color-secondary);
|
||||||
|
--adp-mobile-font-size: 16px;
|
||||||
|
--adp-mobile-nav-height: 40px;
|
||||||
|
--adp-mobile-width: 320px;
|
||||||
|
--adp-mobile-day-cell-height: 38px;
|
||||||
|
--adp-mobile-month-cell-height: 48px;
|
||||||
|
--adp-mobile-year-cell-height: 64px
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-overlay {
|
||||||
|
--adp-overlay-background-color: rgba(0, 0, 0, .3);
|
||||||
|
--adp-overlay-transition-duration: .3s;
|
||||||
|
--adp-overlay-transition-ease: ease-out;
|
||||||
|
--adp-overlay-z-index: 99
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker {
|
||||||
|
background: var(--adp-background-color);
|
||||||
|
border: 1px solid var(--adp-border-color);
|
||||||
|
box-shadow: 0 4px 12px rgba(0,0,0,.15);
|
||||||
|
border-radius: var(--adp-border-radius);
|
||||||
|
box-sizing: content-box;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
grid-template-rows: repeat(4, max-content);
|
||||||
|
grid-template-areas: var(--adp-grid-areas);
|
||||||
|
font-family: var(--adp-font-family),sans-serif;
|
||||||
|
font-size: var(--adp-font-size);
|
||||||
|
color: var(--adp-color);
|
||||||
|
width: var(--adp-width);
|
||||||
|
position: absolute;
|
||||||
|
transition: opacity var(--adp-transition-duration) var(--adp-transition-ease),transform var(--adp-transition-duration) var(--adp-transition-ease);
|
||||||
|
z-index: var(--adp-z-index)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker:not(.-custom-position-) {
|
||||||
|
opacity: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker.-from-top- {
|
||||||
|
transform: translateY(calc(var(--adp-transition-offset) * -1))
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker.-from-right- {
|
||||||
|
transform: translateX(var(--adp-transition-offset))
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker.-from-bottom- {
|
||||||
|
transform: translateY(var(--adp-transition-offset))
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker.-from-left- {
|
||||||
|
transform: translateX(calc(var(--adp-transition-offset) * -1))
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker.-active-:not(.-custom-position-) {
|
||||||
|
transform: translate(0, 0);
|
||||||
|
opacity: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker.-active-.-custom-position- {
|
||||||
|
transition: none
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker.-inline- {
|
||||||
|
border-color: var(--adp-border-color-inline);
|
||||||
|
box-shadow: none;
|
||||||
|
position: static;
|
||||||
|
left: auto;
|
||||||
|
right: auto;
|
||||||
|
opacity: 1;
|
||||||
|
transform: none
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker.-inline- .air-datepicker--pointer {
|
||||||
|
display: none
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker.-is-mobile- {
|
||||||
|
--adp-font-size: var(--adp-mobile-font-size);
|
||||||
|
--adp-day-cell-height: var(--adp-mobile-day-cell-height);
|
||||||
|
--adp-month-cell-height: var(--adp-mobile-month-cell-height);
|
||||||
|
--adp-year-cell-height: var(--adp-mobile-year-cell-height);
|
||||||
|
--adp-nav-height: var(--adp-mobile-nav-height);
|
||||||
|
--adp-nav-action-size: var(--adp-mobile-nav-height);
|
||||||
|
position: fixed;
|
||||||
|
width: var(--adp-mobile-width);
|
||||||
|
border: none
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker.-is-mobile- * {
|
||||||
|
-webkit-tap-highlight-color: rgba(0,0,0,0)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker.-is-mobile- .air-datepicker--pointer {
|
||||||
|
display: none
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker.-is-mobile-:not(.-custom-position-) {
|
||||||
|
transform: translate(-50%, calc(-50% + var(--adp-transition-offset)))
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker.-is-mobile-.-active-:not(.-custom-position-) {
|
||||||
|
transform: translate(-50%, -50%)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker.-custom-position- {
|
||||||
|
transition: none
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-global-container {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker--pointer {
|
||||||
|
--pointer-half-size: calc(var(--adp-pointer-size) / 2);
|
||||||
|
position: absolute;
|
||||||
|
width: var(--adp-pointer-size);
|
||||||
|
height: var(--adp-pointer-size);
|
||||||
|
z-index: -1
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker--pointer:after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
background: #fff;
|
||||||
|
border-top: 1px solid var(--adp-border-color-inline);
|
||||||
|
border-right: 1px solid var(--adp-border-color-inline);
|
||||||
|
border-top-right-radius: var(--adp-poiner-border-radius);
|
||||||
|
width: var(--adp-pointer-size);
|
||||||
|
height: var(--adp-pointer-size);
|
||||||
|
box-sizing: border-box
|
||||||
|
}
|
||||||
|
|
||||||
|
.-top-left- .air-datepicker--pointer, .-top-center- .air-datepicker--pointer, .-top-right- .air-datepicker--pointer, [data-popper-placement^=top] .air-datepicker--pointer {
|
||||||
|
top: calc(100% - var(--pointer-half-size) + 1px)
|
||||||
|
}
|
||||||
|
|
||||||
|
.-top-left- .air-datepicker--pointer:after, .-top-center- .air-datepicker--pointer:after, .-top-right- .air-datepicker--pointer:after, [data-popper-placement^=top] .air-datepicker--pointer:after {
|
||||||
|
transform: rotate(135deg)
|
||||||
|
}
|
||||||
|
|
||||||
|
.-right-top- .air-datepicker--pointer, .-right-center- .air-datepicker--pointer, .-right-bottom- .air-datepicker--pointer, [data-popper-placement^=right] .air-datepicker--pointer {
|
||||||
|
right: calc(100% - var(--pointer-half-size) + 1px)
|
||||||
|
}
|
||||||
|
|
||||||
|
.-right-top- .air-datepicker--pointer:after, .-right-center- .air-datepicker--pointer:after, .-right-bottom- .air-datepicker--pointer:after, [data-popper-placement^=right] .air-datepicker--pointer:after {
|
||||||
|
transform: rotate(225deg)
|
||||||
|
}
|
||||||
|
|
||||||
|
.-bottom-left- .air-datepicker--pointer, .-bottom-center- .air-datepicker--pointer, .-bottom-right- .air-datepicker--pointer, [data-popper-placement^=bottom] .air-datepicker--pointer {
|
||||||
|
bottom: calc(100% - var(--pointer-half-size) + 1px)
|
||||||
|
}
|
||||||
|
|
||||||
|
.-bottom-left- .air-datepicker--pointer:after, .-bottom-center- .air-datepicker--pointer:after, .-bottom-right- .air-datepicker--pointer:after, [data-popper-placement^=bottom] .air-datepicker--pointer:after {
|
||||||
|
transform: rotate(315deg)
|
||||||
|
}
|
||||||
|
|
||||||
|
.-left-top- .air-datepicker--pointer, .-left-center- .air-datepicker--pointer, .-left-bottom- .air-datepicker--pointer, [data-popper-placement^=left] .air-datepicker--pointer {
|
||||||
|
left: calc(100% - var(--pointer-half-size) + 1px)
|
||||||
|
}
|
||||||
|
|
||||||
|
.-left-top- .air-datepicker--pointer:after, .-left-center- .air-datepicker--pointer:after, .-left-bottom- .air-datepicker--pointer:after, [data-popper-placement^=left] .air-datepicker--pointer:after {
|
||||||
|
transform: rotate(45deg)
|
||||||
|
}
|
||||||
|
|
||||||
|
.-top-left- .air-datepicker--pointer, .-bottom-left- .air-datepicker--pointer {
|
||||||
|
left: var(--adp-pointer-offset)
|
||||||
|
}
|
||||||
|
|
||||||
|
.-top-right- .air-datepicker--pointer, .-bottom-right- .air-datepicker--pointer {
|
||||||
|
right: var(--adp-pointer-offset)
|
||||||
|
}
|
||||||
|
|
||||||
|
.-top-center- .air-datepicker--pointer, .-bottom-center- .air-datepicker--pointer {
|
||||||
|
left: calc(50% - var(--adp-pointer-size)/2)
|
||||||
|
}
|
||||||
|
|
||||||
|
.-left-top- .air-datepicker--pointer, .-right-top- .air-datepicker--pointer {
|
||||||
|
top: var(--adp-pointer-offset)
|
||||||
|
}
|
||||||
|
|
||||||
|
.-left-bottom- .air-datepicker--pointer, .-right-bottom- .air-datepicker--pointer {
|
||||||
|
bottom: var(--adp-pointer-offset)
|
||||||
|
}
|
||||||
|
|
||||||
|
.-left-center- .air-datepicker--pointer, .-right-center- .air-datepicker--pointer {
|
||||||
|
top: calc(50% - var(--adp-pointer-size)/2)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker--navigation {
|
||||||
|
grid-area: nav
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker--content {
|
||||||
|
box-sizing: content-box;
|
||||||
|
padding: var(--adp-padding);
|
||||||
|
grid-area: body
|
||||||
|
}
|
||||||
|
|
||||||
|
.-only-timepicker- .air-datepicker--content {
|
||||||
|
display: none
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker--time {
|
||||||
|
grid-area: timepicker
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker--buttons {
|
||||||
|
grid-area: buttons
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker--buttons, .air-datepicker--time {
|
||||||
|
padding: var(--adp-padding);
|
||||||
|
border-top: 1px solid var(--adp-border-color-inner)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-overlay {
|
||||||
|
position: fixed;
|
||||||
|
background: var(--adp-overlay-background-color);
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity var(--adp-overlay-transition-duration) var(--adp-overlay-transition-ease),left 0s,height 0s,width 0s;
|
||||||
|
transition-delay: 0s,var(--adp-overlay-transition-duration),var(--adp-overlay-transition-duration),var(--adp-overlay-transition-duration);
|
||||||
|
z-index: var(--adp-overlay-z-index)
|
||||||
|
}
|
||||||
|
|
||||||
|
.air-datepicker-overlay.-active- {
|
||||||
|
opacity: 1;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
transition: opacity var(--adp-overlay-transition-duration) var(--adp-overlay-transition-ease),height 0s,width 0s
|
||||||
|
}
|
13
AppLibs/AppLibs/wwwroot/css/atg-lib/swiper-bundle.min.css
vendored
Normal file
13
AppLibs/AppLibs/wwwroot/css/atg-lib/swiper-bundle.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
7
AppLibs/AppLibs/wwwroot/css/atg-lib/waves.min.css
vendored
Normal file
7
AppLibs/AppLibs/wwwroot/css/atg-lib/waves.min.css
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
/*!
|
||||||
|
* Waves v0.7.6
|
||||||
|
* http://fian.my.id/Waves
|
||||||
|
*
|
||||||
|
* Copyright 2014-2018 Alfiana E. Sibuea and other contributors
|
||||||
|
* Released under the MIT license
|
||||||
|
* https://github.com/fians/Waves/blob/master/LICENSE */.waves-effect{position:relative;cursor:pointer;display:inline-block;overflow:hidden;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}.waves-effect .waves-ripple{position:absolute;border-radius:50%;width:100px;height:100px;margin-top:-50px;margin-left:-50px;opacity:0;background:rgba(0,0,0,.2);background:-webkit-radial-gradient(rgba(0,0,0,.2) 0,rgba(0,0,0,.3) 40%,rgba(0,0,0,.4) 50%,rgba(0,0,0,.5) 60%,rgba(255,255,255,0) 70%);background:-o-radial-gradient(rgba(0,0,0,.2) 0,rgba(0,0,0,.3) 40%,rgba(0,0,0,.4) 50%,rgba(0,0,0,.5) 60%,rgba(255,255,255,0) 70%);background:-moz-radial-gradient(rgba(0,0,0,.2) 0,rgba(0,0,0,.3) 40%,rgba(0,0,0,.4) 50%,rgba(0,0,0,.5) 60%,rgba(255,255,255,0) 70%);background:radial-gradient(rgba(0,0,0,.2) 0,rgba(0,0,0,.3) 40%,rgba(0,0,0,.4) 50%,rgba(0,0,0,.5) 60%,rgba(255,255,255,0) 70%);-webkit-transition:all .5s ease-out;-moz-transition:all .5s ease-out;-o-transition:all .5s ease-out;transition:all .5s ease-out;-webkit-transition-property:-webkit-transform,opacity;-moz-transition-property:-moz-transform,opacity;-o-transition-property:-o-transform,opacity;transition-property:transform,opacity;-webkit-transform:scale(0) translate(0,0);-moz-transform:scale(0) translate(0,0);-ms-transform:scale(0) translate(0,0);-o-transform:scale(0) translate(0,0);transform:scale(0) translate(0,0);pointer-events:none}.waves-effect.waves-light .waves-ripple{background:rgba(255,255,255,.4);background:-webkit-radial-gradient(rgba(255,255,255,.2) 0,rgba(255,255,255,.3) 40%,rgba(255,255,255,.4) 50%,rgba(255,255,255,.5) 60%,rgba(255,255,255,0) 70%);background:-o-radial-gradient(rgba(255,255,255,.2) 0,rgba(255,255,255,.3) 40%,rgba(255,255,255,.4) 50%,rgba(255,255,255,.5) 60%,rgba(255,255,255,0) 70%);background:-moz-radial-gradient(rgba(255,255,255,.2) 0,rgba(255,255,255,.3) 40%,rgba(255,255,255,.4) 50%,rgba(255,255,255,.5) 60%,rgba(255,255,255,0) 70%);background:radial-gradient(rgba(255,255,255,.2) 0,rgba(255,255,255,.3) 40%,rgba(255,255,255,.4) 50%,rgba(255,255,255,.5) 60%,rgba(255,255,255,0) 70%)}.waves-effect.waves-classic .waves-ripple{background:rgba(0,0,0,.2)}.waves-effect.waves-classic.waves-light .waves-ripple{background:rgba(255,255,255,.4)}.waves-notransition{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;transition:none!important}.waves-button,.waves-circle{-webkit-transform:translateZ(0);-moz-transform:translateZ(0);-ms-transform:translateZ(0);-o-transform:translateZ(0);transform:translateZ(0);-webkit-mask-image:-webkit-radial-gradient(circle,#fff 100%,#000 100%)}.waves-button,.waves-button-input,.waves-button:hover,.waves-button:visited{white-space:nowrap;vertical-align:middle;cursor:pointer;border:none;outline:0;color:inherit;background-color:rgba(0,0,0,0);font-size:1em;line-height:1em;text-align:center;text-decoration:none;z-index:1}.waves-button{padding:.85em 1.1em;border-radius:.2em}.waves-button-input{margin:0;padding:.85em 1.1em}.waves-input-wrapper{border-radius:.2em;vertical-align:bottom}.waves-input-wrapper.waves-button{padding:0}.waves-input-wrapper .waves-button-input{position:relative;top:0;left:0;z-index:1}.waves-circle{text-align:center;width:2.5em;height:2.5em;line-height:2.5em;border-radius:50%}.waves-float{-webkit-mask-image:none;-webkit-box-shadow:0 1px 1.5px 1px rgba(0,0,0,.12);box-shadow:0 1px 1.5px 1px rgba(0,0,0,.12);-webkit-transition:all .3s;-moz-transition:all .3s;-o-transition:all .3s;transition:all .3s}.waves-float:active{-webkit-box-shadow:0 8px 20px 1px rgba(0,0,0,.3);box-shadow:0 8px 20px 1px rgba(0,0,0,.3)}.waves-block{display:block}
|
380
AppLibs/AppLibs/wwwroot/css/atg-ui/atg-gui.css
Normal file
380
AppLibs/AppLibs/wwwroot/css/atg-ui/atg-gui.css
Normal file
@ -0,0 +1,380 @@
|
|||||||
|
/*Scrollbar*/
|
||||||
|
[data-scrollbar], [scrollbar], scrollbar {
|
||||||
|
display: block;
|
||||||
|
position: relative
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Overlay*/
|
||||||
|
.c-overlay {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 12;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
opacity: 0;
|
||||||
|
transition: all ease-in-out .4s;
|
||||||
|
background: rgb(86 83 96 / 0.32)
|
||||||
|
}
|
||||||
|
|
||||||
|
.c-overlay.show {
|
||||||
|
opacity: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
padding: 0 20px
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group label {
|
||||||
|
font-size: .8rem;
|
||||||
|
margin-bottom: 5px
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group .invalid, .form-group .invalid:focus {
|
||||||
|
border-color: #ea5455;
|
||||||
|
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23ea5455'%3E%3Ccircle cx='6' cy='6' r='4.5'/%3E%3Cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3E%3Ccircle cx='6' cy='8.2' r='.6' fill='%23ea5455' stroke='none'/%3E%3C/svg%3E");
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: 20px;
|
||||||
|
background-position: right 0.4rem center
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group input:disabled {
|
||||||
|
background-color: #efefef
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group > .input-custom {
|
||||||
|
border: 1px solid #d8d6de;
|
||||||
|
border-radius: .357rem;
|
||||||
|
-webkit-transition: border-color .15s ease-in-out,-webkit-box-shadow .15s ease-in-out;
|
||||||
|
transition: border-color .15s ease-in-out,-webkit-box-shadow .15s ease-in-out;
|
||||||
|
transition: border-color .15s ease-in-out,box-shadow .15s ease-in-out;
|
||||||
|
transition: border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-box-shadow .15s ease-in-out
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group > .input-custom input {
|
||||||
|
border: none !important
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group > .input-custom:focus-within .input-append.right, .form-group > .input-custom:focus-within .input-append.left {
|
||||||
|
border-color: #7367f0
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group .minus, .form-group .plus {
|
||||||
|
cursor: pointer
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group > .input-custom .input-append {
|
||||||
|
padding: .438rem 1rem;
|
||||||
|
margin-bottom: 0;
|
||||||
|
text-align: center;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: .357rem;
|
||||||
|
transition: border-color .15s ease-in-out,box-shadow .15s ease-in-out
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group > .input-custom .input-append.right {
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
border-left: 1px solid #d8d6de
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group > .input-custom .input-append.left {
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
border-right: 1px solid #d8d6de
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group input, .form-group .aselect, .form-group textarea {
|
||||||
|
font-size: .85rem;
|
||||||
|
width: 100%;
|
||||||
|
cursor: text;
|
||||||
|
padding: 8px 25px 8px 15px;
|
||||||
|
height: 38px;
|
||||||
|
background-color: #fff;
|
||||||
|
background-clip: padding-box;
|
||||||
|
border: 1px solid #d8d6de;
|
||||||
|
border-radius: .357rem;
|
||||||
|
-webkit-transition: border-color .15s ease-in-out,-webkit-box-shadow .15s ease-in-out;
|
||||||
|
transition: border-color .15s ease-in-out,-webkit-box-shadow .15s ease-in-out;
|
||||||
|
transition: border-color .15s ease-in-out,box-shadow .15s ease-in-out;
|
||||||
|
transition: border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-box-shadow .15s ease-in-out
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group textarea {
|
||||||
|
height: auto !important;
|
||||||
|
resize: none
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-checkbox {
|
||||||
|
min-height: 18px;
|
||||||
|
padding-left: 25px;
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-checkbox input[type=checkbox]:checked ~ .a-checkbox-label:before {
|
||||||
|
box-shadow: 0 2px 4px 0 rgba(115,103,240,.4) !important;
|
||||||
|
border-color: #7367f0;
|
||||||
|
background-color: #7367f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=checkbox] {
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
padding: 0;
|
||||||
|
left: 0;
|
||||||
|
margin: 0;
|
||||||
|
position: absolute;
|
||||||
|
z-index: -1;
|
||||||
|
opacity: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-checkbox-label {
|
||||||
|
position: static;
|
||||||
|
display: block;
|
||||||
|
margin: 0 !important
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-checkbox-label::before {
|
||||||
|
background-color: #fff;
|
||||||
|
border: 1px solid #d8d6de;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-checkbox-label::before, .a-checkbox-label::after {
|
||||||
|
position: absolute;
|
||||||
|
display: block;
|
||||||
|
content: '';
|
||||||
|
left: 0;
|
||||||
|
border-radius: 3px;
|
||||||
|
width: 18px;
|
||||||
|
height: 18px
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-checkbox-label::after {
|
||||||
|
background: no-repeat 50%/50% 50%;
|
||||||
|
background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 9.5 7.5'%3E%3Cpolyline points='0.75 4.35 4.18 6.75 8.75 0.75' style='fill:none;stroke:%23fff;stroke-linecap:round;stroke-linejoin:round;stroke-width:1.5px'/%3E%3C/svg%3E");
|
||||||
|
background-size: 57%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*ASelect*/
|
||||||
|
.con-aselect .hide {
|
||||||
|
overflow: hidden;
|
||||||
|
height: 0px !important
|
||||||
|
}
|
||||||
|
|
||||||
|
.con-aselect .hide select:empty {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.aselect {
|
||||||
|
background: #fff !important;
|
||||||
|
cursor: pointer !important
|
||||||
|
}
|
||||||
|
|
||||||
|
.aselect .icon {
|
||||||
|
position: absolute;
|
||||||
|
right: 8px;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
transition: .3s all ease-in-out;
|
||||||
|
color: #6e6b7b
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.con-aselect.active > .aselect > .icon {
|
||||||
|
transform: translateY(-50%) rotate(180deg)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.a-s-sub {
|
||||||
|
margin-top: 10px;
|
||||||
|
max-height: 250px
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-s-sub .a-search {
|
||||||
|
padding: 10px
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-s-sub .noitem {
|
||||||
|
font-size: .85rem;
|
||||||
|
padding: 10px 15px
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-s-sub .a-search input:focus {
|
||||||
|
border-color: #6e6b7b
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-s-sub .a-option {
|
||||||
|
font-size: .85rem;
|
||||||
|
padding: 10px 15px;
|
||||||
|
cursor: default;
|
||||||
|
transition: all .3s ease-in-out
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-s-sub .a-option-group {
|
||||||
|
padding: 10px 15px;
|
||||||
|
font-weight: 600;
|
||||||
|
cursor: default
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-option-group ~ .a-option {
|
||||||
|
padding-left: 25px !important
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-s-sub .a-option:hover {
|
||||||
|
color: #7367f0;
|
||||||
|
background: #eeedfd
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-s-sub .a-option.active {
|
||||||
|
color: white;
|
||||||
|
background: #7367f0
|
||||||
|
}
|
||||||
|
|
||||||
|
.invalid-feedback {
|
||||||
|
display: none;
|
||||||
|
font-size: .85rem;
|
||||||
|
color: #ea5455;
|
||||||
|
}
|
||||||
|
/*From Dropdonw*/
|
||||||
|
|
||||||
|
|
||||||
|
/*Text*/
|
||||||
|
.dt, .dd {
|
||||||
|
padding: 0 20px;
|
||||||
|
font-size: .85rem;
|
||||||
|
line-height: 1.45
|
||||||
|
}
|
||||||
|
|
||||||
|
.dd {
|
||||||
|
color: #6e6b7b
|
||||||
|
}
|
||||||
|
|
||||||
|
.dt {
|
||||||
|
font-weight: 500;
|
||||||
|
color: #6e6b7b
|
||||||
|
}
|
||||||
|
/*Table*/
|
||||||
|
.c-table {
|
||||||
|
width: 100%
|
||||||
|
}
|
||||||
|
|
||||||
|
.c-ta-c {
|
||||||
|
box-shadow: 0 0px 20px 0px rgb(0 0 0 / 15%);
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
/*@media not all and (min-resolution:.001dpcm) {
|
||||||
|
@supports (-webkit-appearance:none) {
|
||||||
|
.c-ta-c {
|
||||||
|
-webkit-mask-image: -webkit-radial-gradient(white, black);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
.c-ta-scroll {
|
||||||
|
-webkit-backface-visibility: hidden;
|
||||||
|
-moz-backface-visibility: hidden;
|
||||||
|
-webkit-transform: translate3d(0, 0, 0);
|
||||||
|
-moz-transform: translate3d(0, 0, 0);
|
||||||
|
overflow: hidden;
|
||||||
|
height: auto !important;
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-table {
|
||||||
|
border-radius: 10px;
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
color: #6e6b7b
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.a-table th {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #36304a;
|
||||||
|
padding: 20px 10px 20px;
|
||||||
|
font-size: .85rem;
|
||||||
|
text-transform: capitalize;
|
||||||
|
letter-spacing: .5px
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-table th:first-child, .a-table td:first-child {
|
||||||
|
padding-left: 25px !important
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.a-table tbody tr:nth-child(even) {
|
||||||
|
background: #f8f6ff
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-table td {
|
||||||
|
color: #808080;
|
||||||
|
padding: 16px 10px 16px 10px;
|
||||||
|
}
|
||||||
|
/*Paging*/
|
||||||
|
.paging {
|
||||||
|
margin: 15px 0
|
||||||
|
}
|
||||||
|
|
||||||
|
.paging .item {
|
||||||
|
height: 32px;
|
||||||
|
width: 32px;
|
||||||
|
color: #6e6b7b;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #f3f2f7;
|
||||||
|
transition: all .3s ease-in-out
|
||||||
|
}
|
||||||
|
|
||||||
|
.paging .item.active {
|
||||||
|
font-weight: 400;
|
||||||
|
color: #fff;
|
||||||
|
background-color: #7367f0 !important
|
||||||
|
}
|
||||||
|
|
||||||
|
.c-page-link {
|
||||||
|
height: 32px;
|
||||||
|
border-radius: 32px;
|
||||||
|
background-color: #f3f2f7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.paging .item:hover {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #7367f0 !important
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-less {
|
||||||
|
margin-right: 10px
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-more {
|
||||||
|
margin-left: 10px
|
||||||
|
}
|
||||||
|
|
||||||
|
.c-table .inpNum {
|
||||||
|
width: 40px;
|
||||||
|
padding: 8px 10px;
|
||||||
|
margin: 15px 8px
|
||||||
|
}
|
||||||
|
|
||||||
|
/*A Overlay*/
|
||||||
|
.c-aoverlay {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 12;
|
||||||
|
opacity: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
transition: all ease-out .5s
|
||||||
|
}
|
||||||
|
|
||||||
|
.c-aoverlay.show {
|
||||||
|
opacity: 1;
|
||||||
|
visibility: visible;
|
||||||
|
background: rgb(86 83 96 / 0.32)
|
||||||
|
}
|
171
AppLibs/AppLibs/wwwroot/css/atg-ui/table.css
Normal file
171
AppLibs/AppLibs/wwwroot/css/atg-ui/table.css
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
/*Table*/
|
||||||
|
|
||||||
|
.abs-pContainer {
|
||||||
|
user-select: none;
|
||||||
|
width: 100%;
|
||||||
|
/* box-shadow: 0 0px 20px 0px rgb(0 0 0 / 15%);
|
||||||
|
*/ border-radius: 10px;
|
||||||
|
}
|
||||||
|
.abs-pContainer [data-scrollbar]{
|
||||||
|
height: 100%!important;
|
||||||
|
}
|
||||||
|
/*@media not all and (min-resolution:.001dpcm) {
|
||||||
|
@supports (-webkit-appearance:none) {
|
||||||
|
.c-ta-c {
|
||||||
|
-webkit-mask-image: -webkit-radial-gradient(white, black);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
.atable-scroll {
|
||||||
|
width: 100% !important
|
||||||
|
}
|
||||||
|
|
||||||
|
.abs-scrollbar {
|
||||||
|
-webkit-backface-visibility: hidden;
|
||||||
|
-moz-backface-visibility: hidden;
|
||||||
|
-webkit-transform: translate3d(0, 0, 0);
|
||||||
|
height: auto !important;
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.abs-table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
.abs-pContainer .scrollbar-thumb {
|
||||||
|
background: #ccc !important
|
||||||
|
}
|
||||||
|
.abs-table {
|
||||||
|
border-radius: 10px;
|
||||||
|
color: #6e6b7b
|
||||||
|
}
|
||||||
|
.abs-table th {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #36304a;
|
||||||
|
padding: 20px 10px 20px;
|
||||||
|
font-size: .9rem;
|
||||||
|
font-weight: 500;
|
||||||
|
text-transform: capitalize;
|
||||||
|
letter-spacing: .5px
|
||||||
|
}
|
||||||
|
|
||||||
|
.abs-table th:first-child, [data-style="default"] .abs-table td:first-child {
|
||||||
|
padding-left: 25px !important
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.abs-table tbody tr:nth-child(even) {
|
||||||
|
background: #f8f6ff
|
||||||
|
}
|
||||||
|
|
||||||
|
.abs-table td {
|
||||||
|
font-size: .82rem;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: 400;
|
||||||
|
color: #808080;
|
||||||
|
padding: 8px 15px
|
||||||
|
}
|
||||||
|
|
||||||
|
.abs-container {
|
||||||
|
box-shadow: 0 0px 20px 0px rgb(0 0 0 / 15%);
|
||||||
|
border-radius: 10px;
|
||||||
|
border: 1px solid #ccc
|
||||||
|
}
|
||||||
|
.abs-table {
|
||||||
|
border-collapse: separate;
|
||||||
|
border-spacing: 0;
|
||||||
|
}
|
||||||
|
.abs-table th:first-child {
|
||||||
|
padding-left: 25px !important
|
||||||
|
}
|
||||||
|
|
||||||
|
.abs-table tbody tr:hover td {
|
||||||
|
background-color: #EBEBEB
|
||||||
|
}
|
||||||
|
.abs-table tbody tr.active td {
|
||||||
|
background-color: rgba(0, 92, 153,.1);
|
||||||
|
border-top: 1px solid rgba(0, 92, 153,.1);
|
||||||
|
border-bottom: 1px solid rgba(0, 92, 153,.1);
|
||||||
|
font-weight: 600;
|
||||||
|
color: #005c99
|
||||||
|
}
|
||||||
|
|
||||||
|
.abs-table tbody tr:hover td:first-child, .abs-table tbody tr.active td:first-child {
|
||||||
|
border-top-left-radius: 5px;
|
||||||
|
border-bottom-left-radius: 5px;
|
||||||
|
}
|
||||||
|
.abs-table tbody tr.active td:first-child {
|
||||||
|
border-left: 1px solid rgba(0, 92, 153,.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.abs-table tbody tr.active td:last-child {
|
||||||
|
border-right: 1px solid rgba(0, 92, 153,.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.abs-table tbody tr:hover td:last-child, .abs-table tbody tr.active td:last-child {
|
||||||
|
border-top-right-radius: 5px;
|
||||||
|
border-bottom-right-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.abs-table tr td:first-child {
|
||||||
|
padding-left: 15px !important
|
||||||
|
}
|
||||||
|
|
||||||
|
.paging .btn-primary {
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
color: #005c99;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.con-paging{
|
||||||
|
font-size:.82rem
|
||||||
|
}
|
||||||
|
|
||||||
|
.paging {
|
||||||
|
margin: 15px 0
|
||||||
|
}
|
||||||
|
|
||||||
|
.paging .item {
|
||||||
|
height: 30px;
|
||||||
|
width: 30px;
|
||||||
|
color: #6e6b7b;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #f3f2f7;
|
||||||
|
text-align: center;
|
||||||
|
transition: all .3s ease-in-out
|
||||||
|
}
|
||||||
|
|
||||||
|
.paging .item.active {
|
||||||
|
font-weight: 400;
|
||||||
|
color: #fff;
|
||||||
|
background-color: #7367f0 !important
|
||||||
|
}
|
||||||
|
|
||||||
|
.c-page-link {
|
||||||
|
height: 30px;
|
||||||
|
border-radius: 32px;
|
||||||
|
background-color: #f3f2f7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.paging .item:hover {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #7367f0 !important
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-less {
|
||||||
|
margin-right: 5px
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-more {
|
||||||
|
margin-left: 5px
|
||||||
|
}
|
||||||
|
|
||||||
|
.con-paging .inpNum {
|
||||||
|
width: 40px;
|
||||||
|
padding: 8px 10px;
|
||||||
|
margin: 15px 8px
|
||||||
|
}
|
BIN
AppLibs/AppLibs/wwwroot/font/ATGIcon-Regular.woff
Normal file
BIN
AppLibs/AppLibs/wwwroot/font/ATGIcon-Regular.woff
Normal file
Binary file not shown.
BIN
AppLibs/AppLibs/wwwroot/font/Branch.woff
Normal file
BIN
AppLibs/AppLibs/wwwroot/font/Branch.woff
Normal file
Binary file not shown.
BIN
AppLibs/AppLibs/wwwroot/font/atg-admin-font.fcp
Normal file
BIN
AppLibs/AppLibs/wwwroot/font/atg-admin-font.fcp
Normal file
Binary file not shown.
BIN
AppLibs/AppLibs/wwwroot/font/atgfont-Regular(1).woff
Normal file
BIN
AppLibs/AppLibs/wwwroot/font/atgfont-Regular(1).woff
Normal file
Binary file not shown.
BIN
AppLibs/AppLibs/wwwroot/font/atgfont-Regular(1).woff2
Normal file
BIN
AppLibs/AppLibs/wwwroot/font/atgfont-Regular(1).woff2
Normal file
Binary file not shown.
15
AppLibs/AppLibs/wwwroot/js/ext_libs/js-datepicker.js
Normal file
15
AppLibs/AppLibs/wwwroot/js/ext_libs/js-datepicker.js
Normal file
File diff suppressed because one or more lines are too long
2
AppLibs/AppLibs/wwwroot/js/ext_libs/js-masonry.min.js
vendored
Normal file
2
AppLibs/AppLibs/wwwroot/js/ext_libs/js-masonry.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
21
AppLibs/AppLibs/wwwroot/js/ext_libs/js-overscroll.js
Normal file
21
AppLibs/AppLibs/wwwroot/js/ext_libs/js-overscroll.js
Normal file
File diff suppressed because one or more lines are too long
2549
AppLibs/AppLibs/wwwroot/js/ext_libs/js-scrollbar.js
Normal file
2549
AppLibs/AppLibs/wwwroot/js/ext_libs/js-scrollbar.js
Normal file
File diff suppressed because it is too large
Load Diff
4155
AppLibs/AppLibs/wwwroot/js/ext_libs/js-scrollbar.min.js
vendored
Normal file
4155
AppLibs/AppLibs/wwwroot/js/ext_libs/js-scrollbar.min.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
4909
AppLibs/AppLibs/wwwroot/js/ext_libs/swiper-bundle.min.js
vendored
Normal file
4909
AppLibs/AppLibs/wwwroot/js/ext_libs/swiper-bundle.min.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
48
AppLibs/AppLibs/wwwroot/js/libs/js-AButton.js
Normal file
48
AppLibs/AppLibs/wwwroot/js/libs/js-AButton.js
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
export default class AButton extends window.AObject {
|
||||||
|
constructor(btn = null) {
|
||||||
|
super();
|
||||||
|
if (btn != null) {
|
||||||
|
if (btn instanceof NodeList) {
|
||||||
|
Array.from(btn).forEach(e => {
|
||||||
|
this.AddEventBtn(el);
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.AddEventBtn(btn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AddEventBtn(e) {
|
||||||
|
var f = function (ev) {
|
||||||
|
if (ev.currentTarget.classList.contains("disabled")) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
this.AddLoading(ev.currentTarget);
|
||||||
|
if (ev.currentTarget.hasAttribute("group-name")) {
|
||||||
|
this.trigger("click_" + ev.currentTarget.getAttribute("group-name"), ev.currentTarget);
|
||||||
|
} else if (ev.currentTarget.hasAttribute("id")) {
|
||||||
|
this.trigger("click_" + ev.currentTarget.getAttribute("id"), ev.currentTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}.bind(this);
|
||||||
|
e.addEventListener("click", f, false);
|
||||||
|
this.stackEvent.push({ "event": "click", "callback": f, "element": e, "parent": null });
|
||||||
|
}
|
||||||
|
AddLoading(e) {
|
||||||
|
e.classList.add("disabled", "d-f", "a-i-center");
|
||||||
|
var a = document.createElement("div");
|
||||||
|
a.classList.add("loader");
|
||||||
|
var b = document.createElement("span");
|
||||||
|
b.textContent = e.textContent;
|
||||||
|
e.innerHTML = "";
|
||||||
|
e.appendChild(a);
|
||||||
|
e.appendChild(b);
|
||||||
|
|
||||||
|
}
|
||||||
|
RemoveLoading(e) {
|
||||||
|
e.classList.remove("disabled", "d-f", "a-i-center");
|
||||||
|
var c = e.querySelector("span");
|
||||||
|
e.textContent = c.textContent;
|
||||||
|
}
|
||||||
|
}
|
121
AppLibs/AppLibs/wwwroot/js/libs/js-ADropdown.js
Normal file
121
AppLibs/AppLibs/wwwroot/js/libs/js-ADropdown.js
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
import ATransitionEffect from '/js/libs/js-ATransitionEffect.js'
|
||||||
|
|
||||||
|
|
||||||
|
export default class Dropdown extends window.AObject {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.transition = new ATransitionEffect();
|
||||||
|
this.isLock = false;
|
||||||
|
if (window.dropdown == null) {
|
||||||
|
this.initGlobalVar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
initGlobalVar() {
|
||||||
|
var f = function (ev) {
|
||||||
|
this.document_onClick.call(this, ev);
|
||||||
|
}.bind(this);
|
||||||
|
document.body.addEventListener("mousedown", f, false);
|
||||||
|
window.dropdown = {
|
||||||
|
"numObj": 1,
|
||||||
|
"callback": f,
|
||||||
|
"currentE": null
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
bindDropDowns(a, p = null) {
|
||||||
|
if (a instanceof NodeList) {
|
||||||
|
Array.from(a).forEach(e => {
|
||||||
|
this.bindDropDown(e, p);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.bindDropDown(a, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
unBindDropDowns(p) {
|
||||||
|
|
||||||
|
}
|
||||||
|
bindDropDown(e, p = null) {
|
||||||
|
var f = function (ev) {
|
||||||
|
this.onClick.call(this, ev);
|
||||||
|
}.bind(this);
|
||||||
|
e.addEventListener("click", f, false);
|
||||||
|
this.stackEvent.push({ "event": "click", "callback": f, "element": e, "parent": p });
|
||||||
|
}
|
||||||
|
document_onClick(e) {
|
||||||
|
this.checkRelease(e);
|
||||||
|
}
|
||||||
|
onClick(e) {
|
||||||
|
if (this.isLock) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var t1 = e.currentTarget;
|
||||||
|
var p = t1.closest('[data-dropdown]');
|
||||||
|
var p1 = e.target.closest(".noopen");
|
||||||
|
if (window.dropdown.currentE != null && (e.target.closest(".item") != null || p1 == null)) {
|
||||||
|
var tmp = window.dropdown.currentE.con;
|
||||||
|
if (window.dropdown.currentE.item.hasAttribute("stopCollapsed")) {
|
||||||
|
window.dropdown.currentE.item.removeAttribute("stopCollapsed")
|
||||||
|
window.dropdown.currentE = null;
|
||||||
|
} else if (e.target.closest(".nonhide") != null) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
this.closeDropdown();
|
||||||
|
}
|
||||||
|
if (tmp.isEqualNode(p)) return;
|
||||||
|
}
|
||||||
|
if (p1 != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
p.classList.add("active");
|
||||||
|
this.trigger("open", t1);
|
||||||
|
var maxHeight = null;
|
||||||
|
var t = p.getElementsByClassName("sub-item")[0];
|
||||||
|
if (t1.hasAttribute("data-width")) {
|
||||||
|
if (t1.getAttribute("data-width") == "auto") {
|
||||||
|
t.style.width = t1.clientWidth + "px";
|
||||||
|
} else {
|
||||||
|
t.style.width = t1.getAttribute("data-width");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (t1.hasAttribute("data-zIndex")) {
|
||||||
|
t.style.zIndex = t1.getAttribute("data-zIndex");
|
||||||
|
}
|
||||||
|
if (t1.hasAttribute("data-max-height")) {
|
||||||
|
maxHeight = t1.getAttribute("data-max-height");
|
||||||
|
t.style.maxHeight = maxHeight + "px";
|
||||||
|
}
|
||||||
|
window.dropdown.currentE = { "con": p, "sub": t, "item": e.currentTarget, "pClass": this, "maxHeight": maxHeight };
|
||||||
|
this.transition.expandEffect(t, function () {
|
||||||
|
this.trigger("opened", t1);
|
||||||
|
}.bind(this), maxHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
checkRelease(e) {
|
||||||
|
if (e.target.closest(".nonhide") != null) {
|
||||||
|
return;
|
||||||
|
} else if (e.target.closest(".scrollbar-track") != null) {
|
||||||
|
return;
|
||||||
|
} else if ((e.target.getAttribute("data-dropdown") == null && e.target.closest("[data-dropdown]") == null) || e.target.closest(".sub-item.show") != null) {
|
||||||
|
this.checkCloseDropdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closeDropdown() {
|
||||||
|
var tm = window.dropdown.currentE;
|
||||||
|
tm.con.classList.remove("active");
|
||||||
|
tm.pClass.trigger("close", tm);
|
||||||
|
this.transition.collapsedEffect(tm.sub, function () {
|
||||||
|
tm.pClass.trigger("closed", tm);
|
||||||
|
}, tm.maxHeight);
|
||||||
|
window.dropdown.currentE = null;
|
||||||
|
}
|
||||||
|
checkCloseDropdown() {
|
||||||
|
if (window.dropdown.currentE != null) {
|
||||||
|
if (!window.dropdown.currentE.item.hasAttribute("stopCollapsed")) {
|
||||||
|
this.closeDropdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
29
AppLibs/AppLibs/wwwroot/js/libs/js-AGrid.js
Normal file
29
AppLibs/AppLibs/wwwroot/js/libs/js-AGrid.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
export default class AGrid extends window.AObject {
|
||||||
|
constructor(options = { "element": null, "grid": "row", "columns": 3, "gutter": "5", "easing":"bounce"}) {
|
||||||
|
this.ele = document.querySelector(options.element);
|
||||||
|
this.wWidth = window.innerWidth || document.body.clientWidth;
|
||||||
|
this.options = options;
|
||||||
|
this.updateWidth();
|
||||||
|
}
|
||||||
|
checkColumn() {
|
||||||
|
this.hItem = 0;
|
||||||
|
if (Array.isArray(this.options.columns)) {
|
||||||
|
for (var i = 0; i < this.options.columns.length; i++) {
|
||||||
|
if (this.wWidth < this.options.columns[i][0]) {
|
||||||
|
this.col = this.options.columns[i][1];
|
||||||
|
if (this.options.columns[i].length > 2) {
|
||||||
|
this.hItem = this.options.columns[i][2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.col = this.options.columns;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
updateWidth() {
|
||||||
|
this.cWidth = this.ele.clientWidth;
|
||||||
|
this.checkColumn();
|
||||||
|
this.wCol = (this.cWidth - (this.options.gutter * (this.col - 1))) / this.col;
|
||||||
|
}
|
||||||
|
}
|
57
AppLibs/AppLibs/wwwroot/js/libs/js-AListBox.js
Normal file
57
AppLibs/AppLibs/wwwroot/js/libs/js-AListBox.js
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import AbsTable from '/js/libs/js-AbsTable.js'
|
||||||
|
|
||||||
|
export default class AListBox extends AbsTable {
|
||||||
|
constructor(e) {
|
||||||
|
super(e);
|
||||||
|
this.absContainer.setAttribute("data-style", "AListBox");
|
||||||
|
this.multiSelect = false;
|
||||||
|
this.selectedID = -1;
|
||||||
|
this.selectedIDs = [];
|
||||||
|
this.selectedItem = null;
|
||||||
|
this.selectedItems = [];
|
||||||
|
this.absRows.addEventListener("click", this.RowClick.bind(this), false);
|
||||||
|
}
|
||||||
|
RemoveItem(id) {
|
||||||
|
|
||||||
|
}
|
||||||
|
CheckSelected(row) {
|
||||||
|
var id = row.getAttribute("data-id");
|
||||||
|
if (this.multiSelect) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (this.selectedID != id) {
|
||||||
|
(this.selectedItem != null)?this.selectedItem.classList.remove("active"):null;
|
||||||
|
this.selectedItem = row;
|
||||||
|
this.selectedID = id;
|
||||||
|
this.selectedItem.classList.add("active");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
checkMultiSeleted(id, ele, f) {
|
||||||
|
if (this.multiSelect) {
|
||||||
|
if (f) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (f) {
|
||||||
|
this.selectedID = id;
|
||||||
|
this.selectedItem = ele;
|
||||||
|
} else {
|
||||||
|
this.selectedID = null;
|
||||||
|
this.selectedItem = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RowClick(e) {
|
||||||
|
var target = e.target;
|
||||||
|
var row = target.closest("tr");
|
||||||
|
if (row != null) {
|
||||||
|
this.CheckSelected(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LoadDataAuto() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
154
AppLibs/AppLibs/wwwroot/js/libs/js-AMenu.js
Normal file
154
AppLibs/AppLibs/wwwroot/js/libs/js-AMenu.js
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
import ADropdown from '/js/libs/js-ADropdown.js'
|
||||||
|
import ATransitionEffect from '/js/libs/js-ATransitionEffect.js'
|
||||||
|
import AOverlay from '/js/libs/js-AOverlay.js';
|
||||||
|
|
||||||
|
export default class AMenu extends window.AObject {
|
||||||
|
constructor(nav, navM, isMDiffD, btnM) {
|
||||||
|
super();
|
||||||
|
this.eleNav = nav;
|
||||||
|
this.navM = document.querySelector(navM);
|
||||||
|
this.navD = document.querySelector(nav);
|
||||||
|
this.transition = new ATransitionEffect();
|
||||||
|
this.overlay = new AOverlay(document.body);
|
||||||
|
this.changeActive();
|
||||||
|
this.isMDiffD = isMDiffD;
|
||||||
|
if (this.isMDiffD) {
|
||||||
|
this.initNavM();
|
||||||
|
this.addEventItemClick(this.navM, false);
|
||||||
|
}
|
||||||
|
var f = function (e) {
|
||||||
|
this.mobileMenu.call(this, e);
|
||||||
|
}.bind(this);
|
||||||
|
btnM.addEventListener("click", f, false);
|
||||||
|
this.stackEvent.push({ "event": "click", "callback": f, "element": btnM, "parent": null });
|
||||||
|
this.overlay.createOverlay();
|
||||||
|
this.overlay.setIndex(2000);
|
||||||
|
this.initDropDown();
|
||||||
|
this.addEventItemClick(this.navD);
|
||||||
|
this.overlay.on("before_close", (function () {
|
||||||
|
this.navM.classList.remove("show");
|
||||||
|
}).bind(this));
|
||||||
|
}
|
||||||
|
initNavM() {
|
||||||
|
this.arr = this.navM.querySelectorAll(".nav-i.has-sub .nav-link");
|
||||||
|
Array.from(this.arr).forEach(el => {
|
||||||
|
var f = function (evt) {
|
||||||
|
this.addEventClick.call(this, evt);
|
||||||
|
}.bind(this);
|
||||||
|
el.addEventListener("click", f, false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
initDropDown() {
|
||||||
|
var d2 = new ADropdown();
|
||||||
|
d2.bindDropDowns(document.querySelectorAll(this.eleNav + " .nav-i.has-sub"));
|
||||||
|
d2.on("closed", (ev1) => {
|
||||||
|
var t = ev1.con.querySelector(".nav-i.active");
|
||||||
|
if (t != null) {
|
||||||
|
ev1.con.classList.add("active");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
addEventItemClick(nav, isNavD = true) {
|
||||||
|
if (nav != null) {
|
||||||
|
var f1 = function (evt) {
|
||||||
|
var item_nav = evt.target.closest("a[app-nav][app-url][nav-id]");
|
||||||
|
if (item_nav != null) {
|
||||||
|
this.trigger("itemClick", item_nav, evt);
|
||||||
|
if (isNavD && this.isMDiffD) {
|
||||||
|
this.d1.checkCloseDropdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.bind(this);
|
||||||
|
nav.addEventListener("click", f1, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateIdPage() {
|
||||||
|
this.idPage = document.head.querySelector("meta[name=idPage]").content;
|
||||||
|
|
||||||
|
this.navActiveD = this.navD.querySelector("a[app-nav][nav-id='" + this.idPage + "']");
|
||||||
|
if (this.isMDiffD) {
|
||||||
|
this.navActiveM = this.navM.querySelector("a[app-nav][nav-id='" + this.idPage + "']");
|
||||||
|
}
|
||||||
|
window.removeStopCollapsed();
|
||||||
|
}
|
||||||
|
changeActive() {
|
||||||
|
this.checkItemActive(false);
|
||||||
|
this.updateIdPage();
|
||||||
|
this.checkItemActive(true);
|
||||||
|
}
|
||||||
|
checkItemActive(f) {
|
||||||
|
this.toggleItemActive(this.navActiveD, f, "Desktop");
|
||||||
|
if (this.isMDiffD) {
|
||||||
|
this.toggleItemActive(this.navActiveM, f);
|
||||||
|
} else {
|
||||||
|
if (this.navActiveD != null) {
|
||||||
|
var t = this.navActiveD.closest("[data-dropdown]");
|
||||||
|
if (t != null) {
|
||||||
|
if (f) {
|
||||||
|
t.setAttribute("stopCollapsed", "")
|
||||||
|
} else {
|
||||||
|
t.removeAttribute("stopCollapsed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
toggleItemActive(e, f, t = "Mobile") {
|
||||||
|
if (e != null) {
|
||||||
|
var hasSubE = e.closest(".has-sub");
|
||||||
|
if (t == "Mobile") {
|
||||||
|
if (f) {
|
||||||
|
(hasSubE != null) ? hasSubE.classList.add("active") : "";
|
||||||
|
e.classList.add("active");
|
||||||
|
} else {
|
||||||
|
(hasSubE != null) ? hasSubE.classList.remove("active") : "";
|
||||||
|
e.classList.remove("active");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (f) {
|
||||||
|
if (hasSubE != null) {
|
||||||
|
hasSubE.classList.add("active")
|
||||||
|
var t1 = hasSubE.querySelector(".sub-item");
|
||||||
|
t1.classList.remove("show");
|
||||||
|
t1.style.height = "auto";
|
||||||
|
t1.style.opacity = 1;
|
||||||
|
}
|
||||||
|
e.classList.add("active");
|
||||||
|
} else {
|
||||||
|
if (hasSubE != null) {
|
||||||
|
hasSubE.classList.remove("active");
|
||||||
|
var t1 = hasSubE.querySelector(".sub-item");
|
||||||
|
t1.classList.remove("show");
|
||||||
|
t1.removeAttribute("style");
|
||||||
|
}
|
||||||
|
e.classList.remove("active");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addEventClick(e) {
|
||||||
|
var p = e.currentTarget.closest(".nav-i");
|
||||||
|
if (!p.classList.contains("active")) {
|
||||||
|
Array.from(this.navM.querySelectorAll(".nav-i.has-sub")).forEach(el => {
|
||||||
|
el.classList.remove("active");
|
||||||
|
});
|
||||||
|
this.transition.expandEffect(p.querySelector(".nav-m-sub"), () => { p.classList.add("active"); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closeExpandMenu() {
|
||||||
|
Array.from(this.navM.querySelectorAll(".nav-i.has-sub")).forEach(el => {
|
||||||
|
el.classList.remove("active");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
mobileMenu(e) {
|
||||||
|
this.overlay.showOverlay();
|
||||||
|
this.navM.classList.add("show");
|
||||||
|
var e1 = this.navM.querySelector(".hd-close");
|
||||||
|
var f1 = function (e) {
|
||||||
|
this.overlay.removeOverlay();
|
||||||
|
}.bind(this);
|
||||||
|
e1.addEventListener("click", f1, false);
|
||||||
|
this.stackEvent.push({ "event": "click", "callback": f1, "element": e1, "parent": "a1" });
|
||||||
|
}
|
||||||
|
}
|
94
AppLibs/AppLibs/wwwroot/js/libs/js-AModal.js
Normal file
94
AppLibs/AppLibs/wwwroot/js/libs/js-AModal.js
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
import AOverlay from '/js/libs/js-AOverlay.js';
|
||||||
|
|
||||||
|
export default class AModal extends window.AObject {
|
||||||
|
constructor(temp) {
|
||||||
|
super();
|
||||||
|
this.overlay = new AOverlay(document.body);
|
||||||
|
this.overlay.isCloseOverlay(false);
|
||||||
|
this.overlay.createOverlay();
|
||||||
|
this.overlay.setIndex(2200);
|
||||||
|
this.customForm = temp;
|
||||||
|
}
|
||||||
|
createModal(typeModal, t1 = 'default') {
|
||||||
|
var temp = `
|
||||||
|
<div class="modal-scroll">
|
||||||
|
<div class="modal-con d-f j-c-center ${ (t1 instanceof Array) ? t1.join(" ") : t1 }">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="btClose pointer">
|
||||||
|
<span class="atg atg-x"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>`;
|
||||||
|
this.overlay.overlay.insertAdjacentHTML("afterbegin", temp);
|
||||||
|
const b = this.overlay.overlay.querySelector(".modal-dialog");
|
||||||
|
const bc1 = this.overlay.overlay.querySelector(".btClose");
|
||||||
|
bc1.addEventListener("click", ((e) => {
|
||||||
|
this.trigger("Close");
|
||||||
|
this.overlay.removeOverlay();
|
||||||
|
}).bind(this));
|
||||||
|
switch (typeModal) {
|
||||||
|
case "CustomForm":
|
||||||
|
b.insertAdjacentHTML("beforeend", this.customForm);
|
||||||
|
this.CustomContainer = b;
|
||||||
|
break;
|
||||||
|
case "OK":
|
||||||
|
this.AModalOK = new AModalOK(b);
|
||||||
|
this.AModalOK.createElement();
|
||||||
|
this.AModalOK.bindEvent(".btn-ok", "click", ((ev, mO) => {
|
||||||
|
this.trigger("OK");
|
||||||
|
this.overlay.removeOverlay();
|
||||||
|
}).bind(this));
|
||||||
|
this.AModalOK.bindEvent(".btn-close", "click", ((ev, mO) => {
|
||||||
|
this.trigger("Close");
|
||||||
|
this.overlay.removeOverlay();
|
||||||
|
}).bind(this));
|
||||||
|
break;
|
||||||
|
case "YesNo":
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
showModal() {
|
||||||
|
this.overlay.showOverlay();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class AModalOK {
|
||||||
|
constructor(p) {
|
||||||
|
this.parent = p;
|
||||||
|
}
|
||||||
|
message(str, classes = "") {
|
||||||
|
this.mess.innerHTML = str;
|
||||||
|
if (classes.length > 0) {
|
||||||
|
Array.from(classes.split(" ")).forEach(el => {
|
||||||
|
this.mess.classList.add(el);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
title(str, classes = "") {
|
||||||
|
this.tit.innerHTML = str;
|
||||||
|
if (classes.length > 0) {
|
||||||
|
Array.from(classes.split(" ")).forEach(el => {
|
||||||
|
this.tit.classList.add(el);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
createElement() {
|
||||||
|
const temp = `<div class="d-f f-c modalok">
|
||||||
|
<h5>Information</h5>
|
||||||
|
<span class="mess-info"></span>
|
||||||
|
<div class="ml-auto mt-2">
|
||||||
|
<button class="btn btn-primary btn-effect waves-effect waves-float btn-ok">Ok</button>
|
||||||
|
<button class="btn btn-secondary btn-effect waves-effect waves-float btn-close">Cancel</button>
|
||||||
|
</div>
|
||||||
|
</div>`;
|
||||||
|
this.parent.insertAdjacentHTML("beforeend", temp);
|
||||||
|
this.tit = this.parent.querySelector("h5");
|
||||||
|
this.mess = this.parent.querySelector(".mess-info");
|
||||||
|
}
|
||||||
|
bindEvent(ele, n, f) {
|
||||||
|
this.parent.querySelector(ele).addEventListener(n, f.bind(null, this));
|
||||||
|
}
|
||||||
|
}
|
47
AppLibs/AppLibs/wwwroot/js/libs/js-AMultiTag.js
Normal file
47
AppLibs/AppLibs/wwwroot/js/libs/js-AMultiTag.js
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
export default class AMultiTag extends window.AObject {
|
||||||
|
constructor(ele) {
|
||||||
|
super();
|
||||||
|
this.parent = ele;
|
||||||
|
this.cItems = ele.querySelector(".input-content");
|
||||||
|
this.itemEles = [];
|
||||||
|
this.itemDatas = [];
|
||||||
|
this.btnAdd = ele.querySelector(".btn-Add");
|
||||||
|
this.btnAdd.addEventListener("click", ((e) => {
|
||||||
|
this.parent.classList.add("active");
|
||||||
|
this.trigger("btnAdd_Click", e);
|
||||||
|
}).bind(this));
|
||||||
|
if (window.AMultiTag == null) {
|
||||||
|
this.initGlobalVar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
initGlobalVar() {
|
||||||
|
var f = function (ev) {
|
||||||
|
if (ev.target.closest(".amultitag") || ev.target.closest(".c-aoverlay")) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
this.parent.classList.remove("active");
|
||||||
|
}
|
||||||
|
}.bind(this);
|
||||||
|
document.body.addEventListener("mousedown", f, false);
|
||||||
|
window.AMultiTag = true;
|
||||||
|
}
|
||||||
|
addItem(id, name, obj, action = null) {
|
||||||
|
var ele = this.addItem(id, name, action);
|
||||||
|
this.itemEles.push(ele);
|
||||||
|
this.itemDatas.push(obj);
|
||||||
|
this.cItems.appendChild(ele);
|
||||||
|
}
|
||||||
|
createItem(id, name, action) {
|
||||||
|
var p = document.createElement("div");
|
||||||
|
p.setAttribute("data-id", id);
|
||||||
|
p.classList.add("item");
|
||||||
|
var label = document.createElement("span");
|
||||||
|
label.innerHTML = name;
|
||||||
|
label.classList.add("name");
|
||||||
|
if (action != null) {
|
||||||
|
p.appendChild(action);
|
||||||
|
}
|
||||||
|
p.appendChild(label);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
}
|
51
AppLibs/AppLibs/wwwroot/js/libs/js-AOverlay.js
Normal file
51
AppLibs/AppLibs/wwwroot/js/libs/js-AOverlay.js
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
export default class AOverlay extends window.AObject {
|
||||||
|
constructor(p) {
|
||||||
|
super();
|
||||||
|
this.parent = p;
|
||||||
|
this.IsActive = false;
|
||||||
|
this.isClose = true;
|
||||||
|
}
|
||||||
|
createOverlay() {
|
||||||
|
var c = document.createElement("div");
|
||||||
|
c.classList.add("c-aoverlay");
|
||||||
|
this.parent.appendChild(c);
|
||||||
|
this.overlay = c;
|
||||||
|
var f = function (e) {
|
||||||
|
this.onOverlay_click.call(this, e);
|
||||||
|
}.bind(this);
|
||||||
|
c.addEventListener("click", f, false);
|
||||||
|
|
||||||
|
}
|
||||||
|
setIndex(i) {
|
||||||
|
this.overlay.style.zIndex = i;
|
||||||
|
}
|
||||||
|
showOverlay() {
|
||||||
|
this.overlay.classList.add("show");
|
||||||
|
this.IsActive = true;
|
||||||
|
}
|
||||||
|
isCloseOverlay(flag) {
|
||||||
|
this.isClose = flag;
|
||||||
|
}
|
||||||
|
addChildNode(childNode) {
|
||||||
|
this.overlay.appendChild(childNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
removeOverlay() {
|
||||||
|
this.trigger("before_close");
|
||||||
|
var f = function (e) {
|
||||||
|
this.IsActive = false;
|
||||||
|
this.trigger("after_close");
|
||||||
|
this.overlay.removeEventListener("transitionend", f, false);
|
||||||
|
}.bind(this);
|
||||||
|
this.overlay.addEventListener("transitionend", f, false);
|
||||||
|
this.overlay.classList.remove("show");
|
||||||
|
|
||||||
|
}
|
||||||
|
onOverlay_click(e) {
|
||||||
|
if ((e.target.classList.contains("modal-con") || e.target.classList.contains("c-aoverlay") )&& this.isClose) {
|
||||||
|
this.removeOverlay();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
145
AppLibs/AppLibs/wwwroot/js/libs/js-APaging.js
Normal file
145
AppLibs/AppLibs/wwwroot/js/libs/js-APaging.js
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
export default class APaging extends window.AObject {
|
||||||
|
constructor(pEle) {
|
||||||
|
super();
|
||||||
|
this.con = pEle;
|
||||||
|
this.activePage = 1;
|
||||||
|
this.bucket = 3;
|
||||||
|
this.listActive = [];
|
||||||
|
this.InitStructure();
|
||||||
|
}
|
||||||
|
SetPaging(maxR) {
|
||||||
|
this.maxRow = maxR;
|
||||||
|
this.numPage = Math.ceil(maxR / this.pageSize);
|
||||||
|
this.lbNum.innerHTML = this.numPage;
|
||||||
|
this.RefreshPaging(this.activePage);
|
||||||
|
}
|
||||||
|
RefreshPaging(page) {
|
||||||
|
this.inpN.value = page;
|
||||||
|
this.activePage = page;
|
||||||
|
this.conPageLinks.innerHTML = "";
|
||||||
|
if (page <= this.bucket - 1) {
|
||||||
|
var length = (this.bucket < this.numPage) ? this.bucket : this.numPage;
|
||||||
|
this.CreatePaging(1, length);
|
||||||
|
} else if (this.numPage - this.activePage <= this.bucket - 2) {
|
||||||
|
this.CreatePaging(this.numPage - this.bucket + 1, this.numPage);
|
||||||
|
} else {
|
||||||
|
this.CreatePaging(this.activePage - 1, this.activePage + this.bucket - 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CreatePaging(start, end) {
|
||||||
|
for (var i = start; i <= end; i++) {
|
||||||
|
var m = this.CreatePageNum(i, "page-link");
|
||||||
|
this.listActive.push(m);
|
||||||
|
this.conPageLinks.appendChild(m);
|
||||||
|
this.CheckActivePage(i, m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CheckActivePage(i, m) {
|
||||||
|
if (i == this.activePage) {
|
||||||
|
this.elActice = m;
|
||||||
|
this.elActice.classList.add("active");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
InitStructure() {
|
||||||
|
var d = document.createElement("div");
|
||||||
|
d.classList.add("d-f", "f-wrap", "con-paging");
|
||||||
|
var d1 = document.createElement("div");
|
||||||
|
d1.classList.add("d-f", "a-i-center");
|
||||||
|
var d2 = document.createElement("span");
|
||||||
|
d2.innerHTML = "Page ";
|
||||||
|
d1.appendChild(d2);
|
||||||
|
var inpNum = document.createElement("input");
|
||||||
|
inpNum.setAttribute("type", "input");
|
||||||
|
inpNum.classList.add("ml-1", "inpNum");
|
||||||
|
d1.appendChild(inpNum);
|
||||||
|
this.inpN = inpNum;
|
||||||
|
var sp = document.createElement("span");
|
||||||
|
sp.innerHTML = " / ";
|
||||||
|
var sp1 = document.createElement("span");
|
||||||
|
sp1.innerHTML = "5";
|
||||||
|
d1.appendChild(sp);
|
||||||
|
d1.appendChild(sp1);
|
||||||
|
this.lbNum = sp1;
|
||||||
|
d.appendChild(d1);
|
||||||
|
d1 = document.createElement("div");
|
||||||
|
d1.classList.add("paging", "d-f", "ml-auto");
|
||||||
|
d1.appendChild(this.CreatePageNum("", "item-less", "atg-less"));
|
||||||
|
d2 = document.createElement("div");
|
||||||
|
d2.classList.add("d-f", "c-page-link");
|
||||||
|
this.conPageLinks = d2;
|
||||||
|
d1.appendChild(d2);
|
||||||
|
d1.appendChild(this.CreatePageNum("", "item-more", "atg-more"));
|
||||||
|
d.appendChild(d1);
|
||||||
|
this.conPaging = d1;
|
||||||
|
this.con.appendChild(d);
|
||||||
|
|
||||||
|
var f = function (evt) {
|
||||||
|
this.ItemClick.call(this, evt);
|
||||||
|
}.bind(this);
|
||||||
|
this.conPaging.addEventListener("click", f, false);
|
||||||
|
f = function (evt) {
|
||||||
|
/*if (this.aOverlay.IsActive) return;*/
|
||||||
|
var selection = window.getSelection().toString();
|
||||||
|
if (selection !== '') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var arr = [38, 40, 37, 39];
|
||||||
|
if (arr.includes(evt.keyCode)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var input = evt.currentTarget.value;
|
||||||
|
input = input.replace(/[^0-9\.]+/g, "");
|
||||||
|
if (input != "") {
|
||||||
|
input = parseInt(input);
|
||||||
|
if (input >= 1 && input <= this.numPage && input != this.activePage) {
|
||||||
|
this.activePage = input;
|
||||||
|
this.trigger("PagingChange", { "numPage": this.numPage, "pageSize": this.pageSize, "activePage": this.activePage });
|
||||||
|
this.RefreshPaging(this.activePage);
|
||||||
|
} else {
|
||||||
|
input = this.activePage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
evt.currentTarget.value = input;
|
||||||
|
|
||||||
|
}.bind(this);
|
||||||
|
this.inpN.addEventListener("keyup", f, false);
|
||||||
|
f = function (evt) {
|
||||||
|
if (evt.currentTarget.value == "") evt.currentTarget.value = this.activePage;
|
||||||
|
}.bind(this);
|
||||||
|
this.inpN.addEventListener("blur", f, false);
|
||||||
|
}
|
||||||
|
ItemClick(e) {
|
||||||
|
if (e.target.classList.contains("page-link") && e.target.classList.contains("active")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var clst = e.target.closest(".item-less");
|
||||||
|
if (clst) {
|
||||||
|
if (this.elActice.previousSibling != null) {
|
||||||
|
this.elActice.previousSibling.click();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var clst1 = e.target.closest(".item-more");
|
||||||
|
if (clst1) {
|
||||||
|
if (this.elActice.nextSibling != null) {
|
||||||
|
this.elActice.nextSibling.click();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (e.target.classList.contains("page-link")) {
|
||||||
|
this.RefreshPaging(parseInt(e.target.innerHTML));
|
||||||
|
this.trigger("PagingChange", { "numPage": this.numPage, "pageSize": this.pageSize, "activePage": this.activePage });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CreatePageNum(i, c = null, icon = null) {
|
||||||
|
var d = document.createElement("a");
|
||||||
|
d.setAttribute("href", "javascript:void(0)");
|
||||||
|
d.classList.add("item", "d-f", "j-c-center", "a-i-center", c);
|
||||||
|
d.innerHTML = i;
|
||||||
|
if (icon != null) {
|
||||||
|
var ic = document.createElement("span");
|
||||||
|
ic.classList.add("atg", icon);
|
||||||
|
d.appendChild(ic);
|
||||||
|
}
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
542
AppLibs/AppLibs/wwwroot/js/libs/js-ASelect.js
Normal file
542
AppLibs/AppLibs/wwwroot/js/libs/js-ASelect.js
Normal file
@ -0,0 +1,542 @@
|
|||||||
|
import ADropdown from '/js/libs/js-ADropdown.js'
|
||||||
|
|
||||||
|
class ASelectEle extends window.AObject {
|
||||||
|
constructor(e, id, p) {
|
||||||
|
super();
|
||||||
|
this.dropdown = new ADropdown();
|
||||||
|
this.parent = p;
|
||||||
|
this.id = id;
|
||||||
|
this.isFocus = false;
|
||||||
|
this.isTextSearch = false;
|
||||||
|
this.isSearch = false;
|
||||||
|
this.isMultiSelect = false;
|
||||||
|
this.multiSelectedItem = [];
|
||||||
|
this.element = e;
|
||||||
|
this.selectedByIndex = -1;
|
||||||
|
this.selectedEleItem = null;
|
||||||
|
this.cSubH = null;
|
||||||
|
this.changeSearch = false;
|
||||||
|
this.changeIndex = false;
|
||||||
|
this.isOpen = false;
|
||||||
|
this.o = {
|
||||||
|
damping: 0.25,
|
||||||
|
thumbMinSize: 5,
|
||||||
|
renderByPixel: true,
|
||||||
|
alwaysShowTracks: true,
|
||||||
|
continuousScrolling: true
|
||||||
|
};
|
||||||
|
this.createElement(e);
|
||||||
|
this.updateItem(true);
|
||||||
|
}
|
||||||
|
lockElement(str = "Loading....") {
|
||||||
|
this.dropdown.isLock = true;
|
||||||
|
if (this.isMultiSelect) {
|
||||||
|
var t = this.cSelectedItem.querySelectorAll(".item:not(input.item)");
|
||||||
|
if (t && t.length > 0) t.removeAll();
|
||||||
|
} else {
|
||||||
|
var t = this.cSelectedItem.querySelectorAll("span");
|
||||||
|
if (t && t.length > 0) t.removeAll();
|
||||||
|
}
|
||||||
|
this.createSelectedText(str);
|
||||||
|
this.aSelect.classList.add("lock");
|
||||||
|
}
|
||||||
|
unlockElement() {
|
||||||
|
this.dropdown.isLock = false;
|
||||||
|
var t = this.cSelectedItem.querySelector("span.text");
|
||||||
|
if (t) t.remove();
|
||||||
|
this.aSelect.classList.remove("lock");
|
||||||
|
}
|
||||||
|
updateItem(f = false) {
|
||||||
|
if (this.isMultiSelect) {
|
||||||
|
this.isMultiSelect = [];
|
||||||
|
}
|
||||||
|
this.listGroups = [];
|
||||||
|
this.listItems = [];
|
||||||
|
if (!f) this.resetItem();
|
||||||
|
var listOptions = this.element.querySelectorAll("option");
|
||||||
|
if (listOptions != null) {
|
||||||
|
listOptions.forEach(u => {
|
||||||
|
this.addItem(u.getAttribute("value"), u.innerHTML);
|
||||||
|
});
|
||||||
|
this.update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addGroup(id, text) {
|
||||||
|
var t = this.groupUI(text);
|
||||||
|
this.listGroups.push({ "id": id, "text": text, "subItems": [], "element": t });
|
||||||
|
this.updateHeight();
|
||||||
|
}
|
||||||
|
addItem(id, val) {
|
||||||
|
var it = document.createElement("span");
|
||||||
|
it.classList.add("ellipsis");
|
||||||
|
it.innerHTML = val;
|
||||||
|
this.addCustomItem(id, it, val);
|
||||||
|
}
|
||||||
|
addCustomItem(id, o, vSearch = "", g = null) {
|
||||||
|
if (g != null) {
|
||||||
|
for (var i = 0; i < this.listGroups.length; i++) {
|
||||||
|
if (this.listGroups[i].id = g.id) {
|
||||||
|
var lastE = this.listOptions[i].subitems.element;
|
||||||
|
var t = this.itemSubUI(id, o, lastE);
|
||||||
|
t.setAttribute("index", this.listItems.length);
|
||||||
|
this.listItems.push({ "id": id, "o": o, "vSearch": vSearch, "gParent": this.listGroups[i], "element": t });
|
||||||
|
this.listGroups[i].subItems.push(this.listItems[this.listItems.length - 1]);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var t = this.itemUI(id, o);
|
||||||
|
t.setAttribute("index", this.listItems.length);
|
||||||
|
this.listItems.push({ "id": id, "o": o, "vSearch": vSearch, "gParent": null, "element": t });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
update() {
|
||||||
|
if (!this.isMultiSelect) {
|
||||||
|
if (this.listItems.length == 0 && !this.dropdown.isLock) {
|
||||||
|
this.createSelectedText("Please choose one of the below options");
|
||||||
|
} else {
|
||||||
|
this.updateIndex(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.updateHeight();
|
||||||
|
}
|
||||||
|
setElement(el, str = "active") {
|
||||||
|
if (this.selectedEleItem != null && !this.isMultiSelect) {
|
||||||
|
this.selectedEleItem.classList.remove(str);
|
||||||
|
}
|
||||||
|
el.classList.add(str);
|
||||||
|
this.selectedEleItem = el;
|
||||||
|
}
|
||||||
|
setSelectedItem(value, f = true) {
|
||||||
|
if (f) {
|
||||||
|
for (var i = 0; i < this.listItems.length; i++) {
|
||||||
|
if (this.listItems[i].id == value) {
|
||||||
|
this.updateIndex(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.updateIndex(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getSelectedItem() {
|
||||||
|
return this.selectedItem.id;
|
||||||
|
}
|
||||||
|
updateHeight() {
|
||||||
|
var tmp = (this.cSearch ? this.cSearch.clientHeight : 0);
|
||||||
|
var tmp1 = this.maxHeight - tmp;
|
||||||
|
if (this.scrollSub.clientHeight >= tmp1 && this.cSubH == null) {
|
||||||
|
this.cSubH = (this.maxHeight - tmp - 8);
|
||||||
|
this.cSub.style.minHeight = this.cSubH + "px";
|
||||||
|
if (this.isOpen) {
|
||||||
|
this.cSub.parentNode.style.height = this.maxHeight + "px";
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.scrollSub.clientHeight < tmp1) {
|
||||||
|
this.cSubH = null;
|
||||||
|
this.cSub.style.minHeight = this.scrollSub.clientHeight + "px";
|
||||||
|
if (this.isOpen) {
|
||||||
|
this.cSub.parentNode.style.height = (this.scrollSub.clientHeight + tmp) + "px";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
isItemEqual(it1, it2) {
|
||||||
|
return it1.getAttribute("data-value") === it2.getAttribute("data-value");
|
||||||
|
}
|
||||||
|
updateIndex(idx, f = false) {
|
||||||
|
if (this.isOpen) {
|
||||||
|
this.changeIndex = true;
|
||||||
|
}
|
||||||
|
if (this.isMultiSelect) {
|
||||||
|
if (this.selectedEleItem != null) this.selectedEleItem.classList.remove("hover");
|
||||||
|
|
||||||
|
this.selectedEleItem = this.listItems[idx].element;
|
||||||
|
this.selectedItem = this.listItems[idx];
|
||||||
|
if (f) {
|
||||||
|
if (!this.multiSelectedItem.hasItem(this.selectedEleItem, this.isItemEqual)) {
|
||||||
|
const item = document.createElement("div");
|
||||||
|
item.classList.add("item", "d-f", "a-i-center");
|
||||||
|
item.setAttribute("data-id", idx);
|
||||||
|
this.cSelectedItem.insertBefore(item, this.cSelectedItem.children[0]);
|
||||||
|
this.cloneNodes(this.selectedEleItem, item);
|
||||||
|
item.insertAdjacentHTML("beforeend", `<button class="ml-1 noopen action d-f a-i-center j-c-center"><span class="atg atg-x"></span></button>`);
|
||||||
|
var bt = item.querySelector("button");
|
||||||
|
bt.addEventListener("click", (e => {
|
||||||
|
this.removeItem(e.currentTarget.parentNode);
|
||||||
|
}).bind(this));
|
||||||
|
this.setElement(this.selectedEleItem);
|
||||||
|
this.multiSelectedItem.push(this.selectedEleItem);
|
||||||
|
}
|
||||||
|
this.eleSearch.value = "";
|
||||||
|
this.eleSearch.focus();
|
||||||
|
}
|
||||||
|
this.setElement(this.selectedEleItem, "hover");
|
||||||
|
} else {
|
||||||
|
this.selectedByIndex = idx;
|
||||||
|
if (this.selectedEleItem != null) this.selectedEleItem.classList.remove("active");
|
||||||
|
this.selectedEleItem = this.listItems[idx].element;
|
||||||
|
this.selectedItem = this.listItems[idx];
|
||||||
|
this.removeAllChildNodes(this.cSelectedItem);
|
||||||
|
this.cloneNodes(this.selectedEleItem, this.cSelectedItem);
|
||||||
|
this.setElement(this.selectedEleItem);
|
||||||
|
this.scroll.update();
|
||||||
|
this.scroll.scrollIntoView(this.selectedEleItem, {
|
||||||
|
offsetTop: this.selectedEleItem.clientHeight
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
itemSubUI(id, o, lastE) {
|
||||||
|
var t = this.itemBaseUI(id, o);
|
||||||
|
lastE.parentNode.insertBefore(t, lastE.nextSibling);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
itemUI(id, o) {
|
||||||
|
var t = this.itemBaseUI(id, o);
|
||||||
|
this.scrollSub.appendChild(t);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
itemBaseUI(id, o) {
|
||||||
|
var d = document.createElement("div");
|
||||||
|
d.classList.add("a-option", "nonhide");
|
||||||
|
d.setAttribute("data-value", id);
|
||||||
|
d.appendChild(o);
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
groupUI(text) {
|
||||||
|
var d = document.createElement("div");
|
||||||
|
d.classList.add("a-option-group", "nonhide");
|
||||||
|
d.innerHTML = text;
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
createSelectedUI() {
|
||||||
|
var s = document.createElement("div");
|
||||||
|
s.classList.add("d-f", "a-i-center");
|
||||||
|
if (this.isMultiSelect) {
|
||||||
|
s.classList.add("f-wrap");
|
||||||
|
s.setAttribute("item-multiple", "");
|
||||||
|
} ;
|
||||||
|
this.cSelectedItem = s;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
createSelectedText(text) {
|
||||||
|
var te = document.createElement("span");
|
||||||
|
te.classList.add("ellipsis", "text");
|
||||||
|
te.innerHTML = text;
|
||||||
|
this.cSelectedItem.insertBefore(te, this.cSelectedItem.children[0]);
|
||||||
|
}
|
||||||
|
createSubItemUI() {
|
||||||
|
var s = document.createElement("div");
|
||||||
|
s.classList.add("sub-item", "a-s-sub", "d-f", "f-c");
|
||||||
|
var cs = null, inp = null, sH = 0;
|
||||||
|
|
||||||
|
|
||||||
|
if (this.isSearch || this.isMultiSelect) {
|
||||||
|
|
||||||
|
if (this.isMultiSelect) {
|
||||||
|
const t = `<input class="item nonhide" type="input"/>`;
|
||||||
|
this.cSelectedItem.insertAdjacentHTML("beforeend", t)
|
||||||
|
inp = this.cSelectedItem.querySelector("input.item");
|
||||||
|
} else {
|
||||||
|
cs = document.createElement("div");
|
||||||
|
cs.classList.add("a-search", "nonhide");
|
||||||
|
s.appendChild(cs);
|
||||||
|
inp = document.createElement("input");
|
||||||
|
cs.appendChild(inp);
|
||||||
|
s.appendChild(cs);
|
||||||
|
this.cSearch = cs;
|
||||||
|
}
|
||||||
|
this.eleSearch = inp;
|
||||||
|
var fv = function (e) {
|
||||||
|
if (this.dropdown.isLock) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!this.isFocus) {
|
||||||
|
window.fireEvent(this.aSelect, "click");
|
||||||
|
this.isFocus = true;
|
||||||
|
}
|
||||||
|
this.inputSearchEvent.call(this, e);
|
||||||
|
|
||||||
|
}.bind(this);
|
||||||
|
inp.addEventListener("keyup", fv, false);
|
||||||
|
var fv1 = function (e) {
|
||||||
|
this.keyDown.call(this, e);
|
||||||
|
}.bind(this);
|
||||||
|
inp.addEventListener("keydown", fv1, false);
|
||||||
|
|
||||||
|
}
|
||||||
|
var sub = document.createElement("div");
|
||||||
|
sub.classList.add("w-100");
|
||||||
|
sub.setAttribute("style", "height:auto");
|
||||||
|
this.cSub = sub;
|
||||||
|
var s1 = document.createElement("div");
|
||||||
|
s1.classList.add("d-f", "f-c", "sub-items");
|
||||||
|
sub.appendChild(s1);
|
||||||
|
this.scrollSub = s1;
|
||||||
|
s.appendChild(sub);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
createElement(e) {
|
||||||
|
var d = document.createElement("div");
|
||||||
|
d.classList.add("con-aselect");
|
||||||
|
if (e.getAttribute("data-container-width") != null) {
|
||||||
|
d.style.width = e.getAttribute("data-container-width");
|
||||||
|
}
|
||||||
|
d.setAttribute("data-dropdown", "");
|
||||||
|
var cselect = document.createElement("div");
|
||||||
|
cselect.classList.add("hide");
|
||||||
|
d.appendChild(cselect);
|
||||||
|
var f = document.createElement("div");
|
||||||
|
for (var i = 0; i < e.classList.length; i++) {
|
||||||
|
f.classList.add(e.classList[i]);
|
||||||
|
}
|
||||||
|
var atts = e.attributes;
|
||||||
|
for (var i = 0; i < atts.length; i++) {
|
||||||
|
if (atts[i].nodeName == "id" || atts[i].nodeName == "name") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (atts[i].nodeName == "data-max-height") {
|
||||||
|
this.maxHeight = atts[i].nodeValue;
|
||||||
|
}
|
||||||
|
f.setAttribute(atts[i].nodeName, atts[i].nodeValue);
|
||||||
|
e.removeAttribute(atts[i].nodeName);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
d.appendChild(f);
|
||||||
|
this.aSelect = f;
|
||||||
|
this.isMultiSelect = f.hasAttribute("isMultiple");
|
||||||
|
this.selectedUI = this.createSelectedUI();
|
||||||
|
f.appendChild(this.selectedUI);
|
||||||
|
var ic = document.createElement("div");
|
||||||
|
ic.classList.add("icon", "atg", "a-down-thick");
|
||||||
|
f.appendChild(ic);
|
||||||
|
this.isSearch = f.hasAttribute("isSearch") && !this.isMultiSelect;
|
||||||
|
d.appendChild(this.createSubItemUI());
|
||||||
|
this.conSelect = d;
|
||||||
|
e.parentNode.insertBefore(d, e);
|
||||||
|
this.conSelect = d;
|
||||||
|
cselect.appendChild(e);
|
||||||
|
this.dropdown.bindDropDowns(f);
|
||||||
|
this.scroll = Scrollbar.init(this.cSub, this.o);
|
||||||
|
f.setAttribute("data-select-id", this.id);
|
||||||
|
this.dropdown.on("opened", function (ev) {
|
||||||
|
this.isFocus = true;
|
||||||
|
this.isOpen = true;
|
||||||
|
if (this.isMultiSelect) {
|
||||||
|
this.eleSearch.focus();
|
||||||
|
this.listItems.forEach(e => { e.element.classList.remove("hover") });
|
||||||
|
this.selectedEleItem = this.listItems[0].element;
|
||||||
|
this.listItems[0].element.classList.add("hover");
|
||||||
|
}
|
||||||
|
}.bind(this));
|
||||||
|
this.dropdown.on("closed", function (ev) {
|
||||||
|
this.isFocus = false;
|
||||||
|
this.isOpen = false;
|
||||||
|
if ((this.isSearch && this.isTextSearch) || this.isMultiSelect) {
|
||||||
|
this.isTextSearch = false;
|
||||||
|
this.eleSearch.value = "";
|
||||||
|
this.resetItem(false);
|
||||||
|
this.updateHeight();
|
||||||
|
}
|
||||||
|
if (this.changeIndex) {
|
||||||
|
this.trigger("change", this);
|
||||||
|
this.changeIndex = false;
|
||||||
|
} else {
|
||||||
|
this.scroll.scrollIntoView(this.selectedEleItem, {
|
||||||
|
offsetTop: 0,
|
||||||
|
onlyScrollIfNeeded: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}.bind(this));
|
||||||
|
if (isTouchAvailable && getOS() === "iOS") {
|
||||||
|
e.classList.add("ios");
|
||||||
|
}
|
||||||
|
var fv1 = function (ev) {
|
||||||
|
this.keyDown.call(this, ev);
|
||||||
|
}.bind(this);
|
||||||
|
e.addEventListener("keydown", fv1, false);
|
||||||
|
var fc = function (e) {
|
||||||
|
this.subItemClick.call(this, e);
|
||||||
|
}.bind(this);
|
||||||
|
var f3 = function (ev) {
|
||||||
|
ev.preventDefault();
|
||||||
|
if (!this.isFocus) {
|
||||||
|
window.fireEvent(f, "click");
|
||||||
|
this.isFocus = true;
|
||||||
|
}
|
||||||
|
}.bind(this);
|
||||||
|
e.addEventListener("focus", f3, false);
|
||||||
|
var f4 = function (ev) {
|
||||||
|
ev.preventDefault();
|
||||||
|
if (!this.isFocus) {
|
||||||
|
this.dropdown.checkCloseDropdown();
|
||||||
|
}
|
||||||
|
}.bind(this);
|
||||||
|
e.addEventListener("blur", f4, false);
|
||||||
|
this.scrollSub.addEventListener("click", fc, false);
|
||||||
|
}
|
||||||
|
subItemClick(e) {
|
||||||
|
var p = e.target.closest(".a-option");
|
||||||
|
if (p != null && !p.hasAttribute("data-empty")) {
|
||||||
|
this.updateIndex(p.getAttribute("index"), true);
|
||||||
|
this.dropdown.checkCloseDropdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
keyDown(ev) {
|
||||||
|
var q = this.selectedEleItem;
|
||||||
|
if (ev.keyCode == 40) {
|
||||||
|
ev.preventDefault();
|
||||||
|
this.changeSearch = true;
|
||||||
|
var tmp = q.nextSibling;
|
||||||
|
while (tmp != null && tmp.classList.contains("a-option-group")) {
|
||||||
|
tmp = tmp.nextSibling;
|
||||||
|
}
|
||||||
|
if (tmp != null && tmp.classList.contains("a-option")) {
|
||||||
|
this.updateIndex(tmp.getAttribute("index"));
|
||||||
|
console.log(tmp.offsetTop);
|
||||||
|
this.scroll.scrollIntoView(tmp, {
|
||||||
|
alignToTop: false,
|
||||||
|
offsetBottom: 0,
|
||||||
|
onlyScrollIfNeeded: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ev.keyCode == 38) {
|
||||||
|
ev.preventDefault();
|
||||||
|
this.changeSearch = true;
|
||||||
|
var tmp = q.previousSibling;
|
||||||
|
while (tmp != null && tmp.classList.contains("a-option-group")) {
|
||||||
|
tmp = tmp.previousSibling;
|
||||||
|
}
|
||||||
|
if (tmp != null && tmp.classList.contains("a-option")) {
|
||||||
|
this.updateIndex(tmp.getAttribute("index"));
|
||||||
|
this.scroll.scrollIntoView(tmp, {
|
||||||
|
offsetTop: 0,
|
||||||
|
onlyScrollIfNeeded: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ev.keyCode == 13 || ev.keyCode == 9) {
|
||||||
|
if (ev.keyCode == 13) ev.preventDefault();
|
||||||
|
this.changeSearch = true;
|
||||||
|
if (this.eleSearch !== ev.currentTarget && this.isFocus) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (q.classList.contains("a-option")) {
|
||||||
|
this.eleSearch.value = "";
|
||||||
|
this.dropdown.checkCloseDropdown();
|
||||||
|
this.updateIndex(this.selectedEleItem.getAttribute("index"), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ev.keyCode == 8 && this.isMultiSelect) {
|
||||||
|
if (this.eleSearch.value.length == 0) {
|
||||||
|
if (this.multiSelectedItem.length > 0) {
|
||||||
|
var t = this.cSelectedItem.querySelectorAll(".item:not(input)");
|
||||||
|
this.removeItem(t[t.length - 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
removeItem(ele) {
|
||||||
|
var l = this.listItems[ele.getAttribute("data-id")].element;
|
||||||
|
l.classList.remove("active");
|
||||||
|
this.multiSelectedItem.removeItem(l, this.isItemEqual);
|
||||||
|
ele.remove();
|
||||||
|
}
|
||||||
|
resetItem(f = true) {
|
||||||
|
if (this.scrollSub.children.length == 0) return;
|
||||||
|
this.scrollSub.removeAll();
|
||||||
|
if (this.listGroups.length == 0) {
|
||||||
|
for (var i = 0; i < this.listItems.length; i++) {
|
||||||
|
this.scrollSub.appendChild(this.listItems[i].element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.scroll.update(true);
|
||||||
|
if (this.isMultiSelect && f) {
|
||||||
|
var t = this.cSelectedItem.querySelectorAll(".item:not(input)");
|
||||||
|
if (t.length > 0) {
|
||||||
|
t.removeAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inputSearchEvent(ev) {
|
||||||
|
if (this.changeSearch) {
|
||||||
|
this.changeSearch = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.isTextSearch = true;
|
||||||
|
this.scrollSub.removeAll();
|
||||||
|
var first = null;
|
||||||
|
if (this.listGroups.length == 0) {
|
||||||
|
for (var i = 0; i < this.listItems.length; i++) {
|
||||||
|
if (this.listItems[i].vSearch.toLowerCase().indexOf(ev.currentTarget.value.toLowerCase()) !== -1) {
|
||||||
|
this.scrollSub.appendChild(this.listItems[i].element);
|
||||||
|
first = (first == null) ? i : first;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/*arr.sub.querySelectorAll(".a-option-group").forEach(e => e.parentNode.removeChild(e));
|
||||||
|
for (var i = 0; i < arr.listEG.length; i++) {
|
||||||
|
var d = document.createElement("div");
|
||||||
|
d.classList.add("a-option-group");
|
||||||
|
d.innerHTML = arr.listEG[i].label;
|
||||||
|
arr.sub.appendChild(d);
|
||||||
|
var c = true;
|
||||||
|
for (var j = 0; j < arr.listEG[i].subitems.length; j++) {
|
||||||
|
if (arr.listEG[i].subitems[j].name.toLowerCase().indexOf(ev.target.value.toLowerCase()) !== -1) {
|
||||||
|
c = false;
|
||||||
|
var tmp = this.addItem(arr.listEG[i].subitems[j]);
|
||||||
|
arr.sub.appendChild(tmp);
|
||||||
|
first = (first == null) ? tmp : first;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (c) d.remove();
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
if (first != null) {
|
||||||
|
this.updateIndex(first);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var it = document.createElement("span");
|
||||||
|
it.classList.add("ellipsis", "text-center");
|
||||||
|
it.innerHTML = "No Result";
|
||||||
|
var item = this.itemBaseUI(null, it);
|
||||||
|
item.classList.add("d-f", "j-c-center");
|
||||||
|
this.scrollSub.appendChild(item);
|
||||||
|
item.setAttribute("data-empty", "");
|
||||||
|
};
|
||||||
|
|
||||||
|
this.updateHeight();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class ASelect extends window.AObject {
|
||||||
|
constructor(e) {
|
||||||
|
super();
|
||||||
|
this.listE = Array.from([]);
|
||||||
|
this.listA = [];
|
||||||
|
this.el = e;
|
||||||
|
this.el.forEach((e) => {
|
||||||
|
if (e.nodeName != "SELECT") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.listA.push(new ASelectEle(e, this.listA.length, this));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
get(id = 0) {
|
||||||
|
if (id >= 0 && id < this.listA.length) {
|
||||||
|
return this.listA[id];
|
||||||
|
} else {
|
||||||
|
console.log("error get Aselect");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getByID(id) {
|
||||||
|
for (var i = 0; i < this.listA.length; i++) {
|
||||||
|
if (this.listA[i].element.getAttribute("id") == id) {
|
||||||
|
return this.listA[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
9
AppLibs/AppLibs/wwwroot/js/libs/js-ASlideBar.js
Normal file
9
AppLibs/AppLibs/wwwroot/js/libs/js-ASlideBar.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import AOverlay from '/js/libs/js-AOverlay.js';
|
||||||
|
export default class ASliderBar extends window.AObject {
|
||||||
|
constructor(o) {
|
||||||
|
super();
|
||||||
|
this.overlay = new AOverlay(document.body);
|
||||||
|
this.overlay.isCloseOverlay(false);
|
||||||
|
this.overlay.createOverlay();
|
||||||
|
}
|
||||||
|
}
|
87
AppLibs/AppLibs/wwwroot/js/libs/js-ASpinButton.js
Normal file
87
AppLibs/AppLibs/wwwroot/js/libs/js-ASpinButton.js
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
export default class ASpinButton extends window.AObject {
|
||||||
|
constructor(ev) {
|
||||||
|
super();
|
||||||
|
this.el = ev;
|
||||||
|
if (ev instanceof NodeList) {
|
||||||
|
this.el.forEach((e) => {
|
||||||
|
this.init(e);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.init(ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
init(e) {
|
||||||
|
var pa = e.closest(".input-custom");
|
||||||
|
var m = pa.querySelector(".minus");
|
||||||
|
var p = pa.querySelector(".plus");
|
||||||
|
var f = function (evt) {
|
||||||
|
this.MinusEvent.call(this, evt, e);
|
||||||
|
}.bind(this);
|
||||||
|
m.addEventListener("click", f, false);
|
||||||
|
var f1 = function (evt) {
|
||||||
|
this.PlusEvent.call(this, evt, e);
|
||||||
|
}.bind(this);
|
||||||
|
p.addEventListener("click", f1, false);
|
||||||
|
var f2 = function (evt) {
|
||||||
|
this.InputChange.call(this, evt);
|
||||||
|
}.bind(this);
|
||||||
|
e.addEventListener("keyup", f2, false);
|
||||||
|
e.value = e.getAttribute("default-value");
|
||||||
|
}
|
||||||
|
MinusEvent(e, inp) {
|
||||||
|
inp.focus();
|
||||||
|
if (inp.value == "") {
|
||||||
|
inp.value = inp.getAttribute("default-value").toLocaleString("us-US");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var v = parseFloat(inp.value.replace(/[,]/g, ''));
|
||||||
|
var step = parseFloat(inp.getAttribute("step-value"));
|
||||||
|
var min = parseFloat(inp.getAttribute("min-value"));
|
||||||
|
if ((v - step) < min) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
inp.value = (v - step).toLocaleString("us-US");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PlusEvent(e, inp) {
|
||||||
|
inp.focus();
|
||||||
|
if (inp.value == "") {
|
||||||
|
inp.value = inp.getAttribute("default-value").toLocaleString("us-US");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var v = parseFloat(inp.value.replace(/[,]/g, ''));
|
||||||
|
var step = parseFloat(inp.getAttribute("step-value"));
|
||||||
|
var max = parseFloat(inp.getAttribute("max-value"));
|
||||||
|
if ((v + step) > max) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
inp.value = (v + step).toLocaleString("us-US");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
InputChange(e) {
|
||||||
|
var selection = window.getSelection().toString();
|
||||||
|
if (selection !== '') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var arr = [38, 40, 37, 39];
|
||||||
|
if (e.currentTarget.hasAttribute("floating-point")) arr.push(190);
|
||||||
|
if (arr.includes(e.keyCode)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var step = parseFloat(e.currentTarget.getAttribute("step-value"));
|
||||||
|
var max = parseFloat(e.currentTarget.getAttribute("max-value"));
|
||||||
|
var min = parseFloat(e.currentTarget.getAttribute("min-value"));
|
||||||
|
var input = e.currentTarget.value;
|
||||||
|
var input = input.replace(/[^\d\.\-]+/g, "");
|
||||||
|
input = parseFloat(input);
|
||||||
|
if (input > max) {
|
||||||
|
input = max;
|
||||||
|
}
|
||||||
|
if (input < min) {
|
||||||
|
input = min
|
||||||
|
}
|
||||||
|
e.currentTarget.value = (e.currentTarget.value == "") ? "" : input.toLocaleString("us-US");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
60
AppLibs/AppLibs/wwwroot/js/libs/js-ATab.js
Normal file
60
AppLibs/AppLibs/wwwroot/js/libs/js-ATab.js
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
export default class ATab extends window.AObject {
|
||||||
|
constructor(tabs, content) {
|
||||||
|
super();
|
||||||
|
this.tabs = tabs.querySelectorAll(".item");
|
||||||
|
this.selTab = null;
|
||||||
|
this.lockTabs = Array.from([]);
|
||||||
|
this.ctabs = Array.from(content.querySelectorAll(".tabcontent"));
|
||||||
|
this.tabs.forEach((e, i) => {
|
||||||
|
if (e.classList.contains("active")) {
|
||||||
|
this.selectedTab(i);
|
||||||
|
}
|
||||||
|
this.ctabs[i].classList.add("fade");
|
||||||
|
e.addEventListener("click", this.eventTabClick.bind(this, e, i));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
eventTabClick(e, num) {
|
||||||
|
if (e.hasAttribute("disabled") || e.classList.contains("active")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.selectedTab(num);
|
||||||
|
}
|
||||||
|
selectedTab(id) {
|
||||||
|
if (this.selTab != null) {
|
||||||
|
if (this.lockTabs.length > 0) {
|
||||||
|
if (this.lockTabs.includes(this.selTab)){
|
||||||
|
this.disableTab(this.selTab);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.tabs[this.selTab].classList.remove("active");
|
||||||
|
this.ctabs[this.selTab].style.opacity = 0;
|
||||||
|
window.requestTimeout(((num) => {
|
||||||
|
this.ctabs[num].classList.remove("show");
|
||||||
|
this.setTab(id);
|
||||||
|
}).bind(this, this.selTab), 100, window.registerCancel);
|
||||||
|
} else {
|
||||||
|
this.setTab(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setTab(id) {
|
||||||
|
this.ctabs[id].classList.add("show");
|
||||||
|
window.requestTimeout((() => {
|
||||||
|
var f = function (ev) {
|
||||||
|
if (ev.propertyName == "opacity") {
|
||||||
|
this.trigger("changed", {"tabIndex": id})
|
||||||
|
ev.target.removeEventListener("transitionend", f, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.ctabs[id].addEventListener('transitionend', f.bind(this), false);
|
||||||
|
this.ctabs[id].style.opacity = 1;
|
||||||
|
}).bind(this), 50, window.registerCancel);
|
||||||
|
this.tabs[id].classList.add("active");
|
||||||
|
this.selTab = id;
|
||||||
|
}
|
||||||
|
enableTab(id) {
|
||||||
|
this.tabs[id].removeAttribute("disabled");
|
||||||
|
}
|
||||||
|
disableTab(id) {
|
||||||
|
this.tabs[id].setAttribute("disabled", "");
|
||||||
|
}
|
||||||
|
}
|
55
AppLibs/AppLibs/wwwroot/js/libs/js-ATable.js
Normal file
55
AppLibs/AppLibs/wwwroot/js/libs/js-ATable.js
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import AbsTable from '/js/libs/js-AbsTable.js'
|
||||||
|
import APaging from '/js/libs/js-APaging.js'
|
||||||
|
import AOverlay from '/js/libs/js-AOverlay.js'
|
||||||
|
|
||||||
|
export default class ATable extends AbsTable {
|
||||||
|
constructor(e, pageSize = 5) {
|
||||||
|
super(e);
|
||||||
|
this.hForm = new FormData();
|
||||||
|
this.absPaging = new APaging(e);
|
||||||
|
this.aOverlay = new AOverlay(e);
|
||||||
|
this.aOverlay.createOverlay();
|
||||||
|
this.absPaging.pageSize = pageSize;
|
||||||
|
this.absPaging.activePage = 1;
|
||||||
|
this.absPaging.maxRow = -1;
|
||||||
|
this.absPaging.on("PagingChange", ((e) => {
|
||||||
|
this.SendData(false);
|
||||||
|
}).bind(this));
|
||||||
|
|
||||||
|
}
|
||||||
|
LoadDataUrl(url, first = true) {
|
||||||
|
this.url = url;
|
||||||
|
this.aOverlay.showOverlay();
|
||||||
|
this.SendData(first);
|
||||||
|
}
|
||||||
|
SendData(first) {
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("POST", this.url);
|
||||||
|
var f = function (evt) {
|
||||||
|
if (evt.currentTarget.readyState == 4 && evt.currentTarget.status == 200) {
|
||||||
|
if (evt.currentTarget.responseText) {
|
||||||
|
var o = JSON.parse(evt.currentTarget.responseText);
|
||||||
|
if (o.mrows != null) {
|
||||||
|
this.absPaging.SetPaging(o.mrows);
|
||||||
|
}
|
||||||
|
this.LoadData(o.data);
|
||||||
|
this.aOverlay.removeOverlay();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.bind(this);
|
||||||
|
xhr.addEventListener("readystatechange", f, false);
|
||||||
|
var frm = new FormData();
|
||||||
|
AddFormData(frm, "isFirstQuery", first);
|
||||||
|
AddFormData(frm, "pageSize", this.absPaging.pageSize);
|
||||||
|
AddFormData(frm, "pageNumber", this.absPaging.activePage);
|
||||||
|
AddFormData(frm, "maxRow", this.absPaging.maxRow);
|
||||||
|
xhr.send(frm);
|
||||||
|
}
|
||||||
|
RefreshPage(page, firstQ = false) {
|
||||||
|
this.absPaging.activePage = page;
|
||||||
|
this.SendData(firstQ);
|
||||||
|
}
|
||||||
|
RefreshCurrentPage(firstQ = false) {
|
||||||
|
this.SendData(firstQ);
|
||||||
|
}
|
||||||
|
}
|
38
AppLibs/AppLibs/wwwroot/js/libs/js-ATransitionEffect.js
Normal file
38
AppLibs/AppLibs/wwwroot/js/libs/js-ATransitionEffect.js
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
export default class ATransitionEffect {
|
||||||
|
constructor() { }
|
||||||
|
collapsedEffect(e, c = null, maxHeight = null) {
|
||||||
|
var height = (maxHeight == null || e.scrollHeight <= maxHeight) ? e.scrollHeight : maxHeight;
|
||||||
|
var transition = e.style.transition;
|
||||||
|
e.style.transition = '';
|
||||||
|
requestAnimationFrame(function () {
|
||||||
|
e.style.height = height + 'px';
|
||||||
|
e.style.opacity = 1;
|
||||||
|
e.style.transition = transition;
|
||||||
|
requestAnimationFrame(function () {
|
||||||
|
e.style.height = 0 + 'px';
|
||||||
|
e.style.opacity = .3
|
||||||
|
});
|
||||||
|
});
|
||||||
|
var f = function (ev) {
|
||||||
|
if (ev.propertyName == "height") {
|
||||||
|
ev.target.classList.remove('show');
|
||||||
|
if (c != null) c.call();
|
||||||
|
}
|
||||||
|
ev.target.removeEventListener("transitionend", f, false);
|
||||||
|
};
|
||||||
|
e.addEventListener('transitionend', f, false);
|
||||||
|
}
|
||||||
|
expandEffect(e, c = null, maxHeight = null) {
|
||||||
|
e.style.opacity = 1;
|
||||||
|
e.style.height = ((maxHeight == null || e.scrollHeight <= maxHeight) ? e.scrollHeight : maxHeight) + 'px';
|
||||||
|
var f = function (ev) {
|
||||||
|
if (ev.propertyName == "height") {
|
||||||
|
ev.target.classList.add("show");
|
||||||
|
ev.target.style.height = null;
|
||||||
|
if (c != null) c.call();
|
||||||
|
ev.target.removeEventListener("transitionend", f, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
e.addEventListener('transitionend', f, false);
|
||||||
|
}
|
||||||
|
}
|
199
AppLibs/AppLibs/wwwroot/js/libs/js-AbsTable.js
Normal file
199
AppLibs/AppLibs/wwwroot/js/libs/js-AbsTable.js
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
export default class AbsTable extends window.AObject {
|
||||||
|
constructor(e) {
|
||||||
|
super();
|
||||||
|
this.data = [];
|
||||||
|
this.idCheckBox = 1;
|
||||||
|
this.pElement = e;
|
||||||
|
this.Headers = [];
|
||||||
|
this.lSysRows = [];
|
||||||
|
this.InitStructure();
|
||||||
|
this.InitCss();
|
||||||
|
this.SetIdCheckBox();
|
||||||
|
}
|
||||||
|
SetIdCheckBox() {
|
||||||
|
if (window.nAbsTable == null) {
|
||||||
|
window.nAbsTable = 1;
|
||||||
|
} else {
|
||||||
|
window.nAbsTable += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SetScrollBarY(height) {
|
||||||
|
this.absContainerRows.style.height = height + "px";
|
||||||
|
}
|
||||||
|
AddHeader(name, width, minWidth, id = "", rowTemp = null) {
|
||||||
|
var d = document.createElement("th");
|
||||||
|
d.innerHTML = name;
|
||||||
|
d.style.width = width;
|
||||||
|
if (id != "") {
|
||||||
|
d.setAttribute("header-id", id);
|
||||||
|
}
|
||||||
|
this.Headers.push({ "id": id, "nameCol": name, "element": d, "rowTemp": rowTemp });
|
||||||
|
this.absHeaders.appendChild(d);
|
||||||
|
if (width == "") {
|
||||||
|
this.UpdateWidth(minWidth);
|
||||||
|
} else {
|
||||||
|
this.UpdateWidth(width);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
UpdateWidth(width) {
|
||||||
|
this.absTableH.style.minWidth = (parseInt(width) + parseInt(this.absTableH.style.minWidth == "" ? 0 : this.absTableH.style.minWidth)) + "px";
|
||||||
|
this.absTable.style.minWidth = this.absTableH.style.minWidth;
|
||||||
|
this.absContainerRows.style.minWidth = this.absTableH.style.minWidth;
|
||||||
|
}
|
||||||
|
AddRow(temp) {
|
||||||
|
if (this.lSysRows.length > 0) {
|
||||||
|
this.absRows.insertBefore(temp, this.lSysRows[0]);
|
||||||
|
} else {
|
||||||
|
this.absRows.appendChild(temp);
|
||||||
|
}
|
||||||
|
temp.querySelectorAll("td").forEach((o, i) => {
|
||||||
|
o.style.width = this.Headers[i].element.style.width;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
AddSysRow(temp, id) {
|
||||||
|
this.absRows.insertBefore(temp, this.absRows.nextSibling);
|
||||||
|
this.lSysRows.push({ "id": id, "element": temp });
|
||||||
|
}
|
||||||
|
InitCss() {
|
||||||
|
this.pElement.classList.add("abs-pContainer");
|
||||||
|
this.absContainer.setAttribute("data-style", "default");
|
||||||
|
this.absContainer.classList.add("abs-container");
|
||||||
|
this.absScrollbar.classList.add("abs-scrollbar");
|
||||||
|
this.absTable.classList.add("abs-table", "virtual");
|
||||||
|
this.absTableH.classList.add("abs-table");
|
||||||
|
}
|
||||||
|
IsCheckBox(f) {
|
||||||
|
this.isCheckBox = f;
|
||||||
|
if (f) {
|
||||||
|
var t = this.InitCheckBox("checkItemAll" + window.nAbsTable);
|
||||||
|
this.UpdateWidth(65);
|
||||||
|
this.absHeaders.insertBefore(t, this.absHeaders.children[0]);
|
||||||
|
this.Headers.unshift({
|
||||||
|
"id": "", "nameCol": "", "element": t, "rowTemp": (function (id, data) {
|
||||||
|
this.idCheckBox += 1;
|
||||||
|
return this.InitCheckBox(("checkEle" + window.nAbsTable) + (this.idCheckBox - 1), false).children[0];
|
||||||
|
}).bind(this)
|
||||||
|
});
|
||||||
|
var cBox = this.absHeaders.querySelector("#checkItemAll" + window.nAbsTable);
|
||||||
|
var evF = function (evt) {
|
||||||
|
this.CheckAll_EvtHandler.call(this, evt);
|
||||||
|
}.bind(this);
|
||||||
|
cBox.addEventListener("change", evF, false);
|
||||||
|
this.stackEvent.push({ "event": "change", "callback": evF, "element": cBox, "parent": null });
|
||||||
|
var lTD = this.absRows.querySelectorAll("tr");
|
||||||
|
lTD.forEach(u => {
|
||||||
|
u.insertBefore(this.InitCheckBox(("checkEle" + window.nAbsTable) + idCheckBox, false), u.children[0]);
|
||||||
|
this.idCheckBox += 1;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
var t = this.absHeaders.querySelector("#checkItemAll" + window.nAbsTable);
|
||||||
|
if (t != null) {
|
||||||
|
this.UpdateWidth(-65);
|
||||||
|
this.removeEvent(t);
|
||||||
|
var tm = this.Headers.shift();
|
||||||
|
tm.element.remove();
|
||||||
|
var lTD = this.absRows.querySelectorAll("tr");
|
||||||
|
lTD.forEach(u => {
|
||||||
|
u.children[0].remove();
|
||||||
|
});
|
||||||
|
this.idCheckBox = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
InitCheckBox(name, isHeader = true) {
|
||||||
|
var td = document.createElement((isHeader) ? "th" : "td");
|
||||||
|
var con = document.createElement("div");
|
||||||
|
con.classList.add("custom-checkbox", "mr-0", "mt-auto", "mb-auto");
|
||||||
|
var cb = document.createElement("input");
|
||||||
|
cb.setAttribute("id", name);
|
||||||
|
cb.setAttribute("type", "checkbox");
|
||||||
|
var lb = document.createElement("label");
|
||||||
|
lb.classList.add("a-checkbox-label");
|
||||||
|
lb.setAttribute("for", name);
|
||||||
|
if (isHeader) {
|
||||||
|
td.style.width = "65px";
|
||||||
|
} else {
|
||||||
|
cb.setAttribute("rowCheck", "");
|
||||||
|
}
|
||||||
|
con.appendChild(cb);
|
||||||
|
con.appendChild(lb);
|
||||||
|
td.appendChild(con);
|
||||||
|
return td
|
||||||
|
}
|
||||||
|
InitStructure() {
|
||||||
|
this.absContainer = document.createElement("div");
|
||||||
|
this.absScrollbar = document.createElement("div");
|
||||||
|
this.absContainer.appendChild(this.absScrollbar);
|
||||||
|
this.pElement.appendChild(this.absContainer);
|
||||||
|
var options = {
|
||||||
|
damping: 0.25,
|
||||||
|
thumbMinSize: 5,
|
||||||
|
renderByPixel: true,
|
||||||
|
alwaysShowTracks: true,
|
||||||
|
continuousScrolling: true,
|
||||||
|
plugins: {
|
||||||
|
overscroll: {
|
||||||
|
effect: 'bounce',
|
||||||
|
damping: 0.15,
|
||||||
|
maxOverscroll: 80
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Scrollbar.init(this.absScrollbar, options);
|
||||||
|
this.absScrollbarCon = this.absScrollbar.querySelector(".scroll-content");
|
||||||
|
this.absTableH = document.createElement("table");
|
||||||
|
this.absTable = document.createElement("table");
|
||||||
|
var d1 = document.createElement("thead");
|
||||||
|
var d2 = document.createElement("tr");
|
||||||
|
this.absTableH.appendChild(d1);
|
||||||
|
this.absHeaders = d2;
|
||||||
|
d1.appendChild(d2);
|
||||||
|
|
||||||
|
d1 = document.createElement("tbody");
|
||||||
|
this.absTable.appendChild(d1);
|
||||||
|
this.absRows = d1;
|
||||||
|
this.absScrollbarCon.appendChild(this.absTableH);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var c = document.createElement("div");
|
||||||
|
c.classList.add("atable-scroll");
|
||||||
|
c.setAttribute("data-scrollbar", "");
|
||||||
|
c.appendChild(this.absTable);
|
||||||
|
this.absContainerRows = c;
|
||||||
|
this.absScrollbarCon.appendChild(c);
|
||||||
|
Scrollbar.init(this.absContainerRows, options);
|
||||||
|
|
||||||
|
}
|
||||||
|
CheckAll_EvtHandler(e) {
|
||||||
|
var listC = this.absRows.querySelectorAll("input[type=checkbox][rowCheck]");
|
||||||
|
listC.forEach(el => {
|
||||||
|
if (e.currentTarget.checked) {
|
||||||
|
el.checked = true;
|
||||||
|
} else {
|
||||||
|
el.checked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
LoadData(data) {
|
||||||
|
this.absRows.innerHTML = "";
|
||||||
|
this.data = JSON.parse(data);
|
||||||
|
|
||||||
|
this.data.forEach((e, i) => {
|
||||||
|
var r = document.createElement("tr");
|
||||||
|
r.setAttribute("data-id", i);
|
||||||
|
this.Headers.forEach((o) => {
|
||||||
|
var td = document.createElement("td");
|
||||||
|
if (o.rowTemp != null) {
|
||||||
|
td.appendChild(o.rowTemp(i, e));
|
||||||
|
} else {
|
||||||
|
td.innerHTML = e[o.id];
|
||||||
|
}
|
||||||
|
r.appendChild(td);
|
||||||
|
});
|
||||||
|
this.AddRow(r);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
620
AppLibs/AppLibs/wwwroot/js/libs/js-core.js
Normal file
620
AppLibs/AppLibs/wwwroot/js/libs/js-core.js
Normal file
@ -0,0 +1,620 @@
|
|||||||
|
|
||||||
|
window.AScript = new Map();
|
||||||
|
window.isTouchAvailable = 'ontouchstart' in window ||
|
||||||
|
window.DocumentTouch && document instanceof window.DocumentTouch ||
|
||||||
|
navigator.maxTouchPoints > 0 ||
|
||||||
|
window.navigator.msMaxTouchPoints > 0
|
||||||
|
|
||||||
|
if (Node.prototype.appendChildren === undefined) {
|
||||||
|
Node.prototype.appendChildren = function () {
|
||||||
|
let children = [...arguments];
|
||||||
|
|
||||||
|
if (
|
||||||
|
children.length == 1 &&
|
||||||
|
Object.prototype.toString.call(children[0]) === "[object Array]"
|
||||||
|
) {
|
||||||
|
children = children[0];
|
||||||
|
}
|
||||||
|
var documentFragment = document.createDocumentFragment();
|
||||||
|
children.forEach(c => documentFragment.appendChild(c));
|
||||||
|
this.appendChild(documentFragment);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (Node.prototype.removeAll === undefined) {
|
||||||
|
Node.prototype.removeAll = function () {
|
||||||
|
while (this.firstChild) this.removeChild(this.lastChild);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (NodeList.prototype.removeAll === undefined) {
|
||||||
|
NodeList.prototype.removeAll = function () {
|
||||||
|
for (var i = this.length - 1; i >= 0; i--) {
|
||||||
|
this[i].remove();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.prototype.hasItem === undefined) {
|
||||||
|
Array.prototype.hasItem = function (o, callback) {
|
||||||
|
var f = false;
|
||||||
|
this.forEach(e => {
|
||||||
|
if (callback(e, o)) {
|
||||||
|
f = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.prototype.removeItem === undefined) {
|
||||||
|
Array.prototype.removeItem = function (o, callback) {
|
||||||
|
var f = false;
|
||||||
|
this.forEach((e, i) => {
|
||||||
|
if (callback(e, o)) {
|
||||||
|
delete this[i];
|
||||||
|
this.splice(i, 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.getOS = function () {
|
||||||
|
var userAgent = window.navigator.userAgent,
|
||||||
|
platform = window.navigator.platform,
|
||||||
|
macosPlatforms = ['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'],
|
||||||
|
windowsPlatforms = ['Win32', 'Win64', 'Windows', 'WinCE'],
|
||||||
|
iosPlatforms = ['iPhone', 'iPad', 'iPod'],
|
||||||
|
os = null;
|
||||||
|
|
||||||
|
if (macosPlatforms.indexOf(platform) !== -1) {
|
||||||
|
os = 'Mac OS';
|
||||||
|
} else if (iosPlatforms.indexOf(platform) !== -1) {
|
||||||
|
os = 'iOS';
|
||||||
|
} else if (windowsPlatforms.indexOf(platform) !== -1) {
|
||||||
|
os = 'Windows';
|
||||||
|
} else if (/Android/.test(userAgent)) {
|
||||||
|
os = 'Android';
|
||||||
|
} else if (!os && /Linux/.test(platform)) {
|
||||||
|
os = 'Linux';
|
||||||
|
}
|
||||||
|
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.GetAbsoluteURL = function (relativeURL) {
|
||||||
|
return window.location.origin + relativeURL;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.GetEventType = function () {
|
||||||
|
if (isTouchAvailable) {
|
||||||
|
return "touchend";
|
||||||
|
} else {
|
||||||
|
return "click";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
window.fireEvent = function (element, event) {
|
||||||
|
if (document.createEventObject) {
|
||||||
|
// dispatch for IE
|
||||||
|
var evt = document.createEventObject();
|
||||||
|
return element.fireEvent('on' + event, evt)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// dispatch for firefox + others
|
||||||
|
var evt = document.createEvent("HTMLEvents");
|
||||||
|
evt.initEvent(event, true, true); // event type,bubbling,cancelable
|
||||||
|
return !element.dispatchEvent(evt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
window.noop = function () { }
|
||||||
|
window.requestTimeout = function (fn, delay, registerCancel) {
|
||||||
|
const start = new Date().getTime();
|
||||||
|
|
||||||
|
const loop = () => {
|
||||||
|
const delta = new Date().getTime() - start;
|
||||||
|
|
||||||
|
if (delta >= delay) {
|
||||||
|
fn();
|
||||||
|
window.registerCancel(window.noop);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const raf = requestAnimationFrame(loop);
|
||||||
|
window.registerCancel(() => cancelAnimationFrame(raf));
|
||||||
|
};
|
||||||
|
|
||||||
|
const raf = requestAnimationFrame(loop);
|
||||||
|
window.registerCancel(() => cancelAnimationFrame(raf));
|
||||||
|
};
|
||||||
|
window.cancel = window.noop;
|
||||||
|
window.registerCancel = function () { };
|
||||||
|
|
||||||
|
window.formatDateToString = function (date) {
|
||||||
|
var dd = (date.getDay() < 10 ? '0' : '') + date.getDay();
|
||||||
|
var MM = ((date.getMonth() + 1) < 10 ? '0' : '') + (date.getMonth() + 1);
|
||||||
|
var yyyy = date.getFullYear();
|
||||||
|
var hh = (date.getHours() < 10 ? '0' : '') + date.getHours();
|
||||||
|
var mm = (date.getMinutes() < 10 ? '0' : '') + date.getMinutes();
|
||||||
|
var ss = (date.getSeconds() < 10 ? '0' : '') + date.getSeconds();
|
||||||
|
return (dd + "-" + MM + "-" + yyyy + " " + hh + ":" + mm + ":" + ss);
|
||||||
|
}
|
||||||
|
window.padLeadingZeros = function (num, size) {
|
||||||
|
var s = num + "";
|
||||||
|
while (s.length < size) s = "0" + s;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
window.AddFormData = function (frm, name, val) {
|
||||||
|
if (frm.has(name)) {
|
||||||
|
frm.set(name, val); v
|
||||||
|
} else {
|
||||||
|
frm.append(name, val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.checkViewHeight = function () {
|
||||||
|
let vh = window.innerHeight * 0.01;
|
||||||
|
document.documentElement.style.setProperty('--vh', `${vh}px`);
|
||||||
|
}
|
||||||
|
window.checkViewHeight();
|
||||||
|
window.addEventListener('resize', () => {
|
||||||
|
window.checkViewHeight();
|
||||||
|
});
|
||||||
|
window.AObject = class {
|
||||||
|
constructor() {
|
||||||
|
this.listeners = new Map();
|
||||||
|
this.onceListeners = new Map();
|
||||||
|
this.triggerdLabels = new Map();
|
||||||
|
this.stackEvent = Array.from([]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// help-function for onReady and onceReady
|
||||||
|
// the callbackfunction will execute,
|
||||||
|
// if the label has already been triggerd with the last called parameters
|
||||||
|
_fCheckPast(label, callback) {
|
||||||
|
if (this.triggerdLabels.has(label)) {
|
||||||
|
callback(this.triggerdLabels.get(label));
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// execute the callback everytime the label is trigger
|
||||||
|
on(label, callback, checkPast = false) {
|
||||||
|
this.listeners.has(label) || this.listeners.set(label, []);
|
||||||
|
this.listeners.get(label).push(callback);
|
||||||
|
if (checkPast)
|
||||||
|
this._fCheckPast(label, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
// execute the callback everytime the label is trigger
|
||||||
|
// check if the label had been already called
|
||||||
|
// and if so excute the callback immediately
|
||||||
|
onReady(label, callback) {
|
||||||
|
this.on(label, callback, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// execute the callback onetime the label is trigger
|
||||||
|
once(label, callback, checkPast = false) {
|
||||||
|
this.onceListeners.has(label) || this.onceListeners.set(label, []);
|
||||||
|
if (!(checkPast && this._fCheckPast(label, callback))) {
|
||||||
|
// label wurde nocht nicht aufgerufen und
|
||||||
|
// der callback in _fCheckPast nicht ausgeführt
|
||||||
|
this.onceListeners.get(label).push(callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// execute the callback onetime the label is trigger
|
||||||
|
// or execute the callback if the label had been called already
|
||||||
|
onceReady(label, callback) {
|
||||||
|
this.once(label, callback, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove the callback for a label
|
||||||
|
off(label, callback = true) {
|
||||||
|
if (callback === true) {
|
||||||
|
// remove listeners for all callbackfunctions
|
||||||
|
this.listeners.delete(label);
|
||||||
|
this.onceListeners.delete(label);
|
||||||
|
} else {
|
||||||
|
// remove listeners only with match callbackfunctions
|
||||||
|
let _off = (inListener) => {
|
||||||
|
let listeners = inListener.get(label);
|
||||||
|
if (listeners) {
|
||||||
|
inListener.set(label, listeners.filter((value) => !(value === callback)));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
_off(this.listeners);
|
||||||
|
_off(this.onceListeners);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// trigger the event with the label
|
||||||
|
trigger(label, ...args) {
|
||||||
|
let res = false;
|
||||||
|
this.triggerdLabels.set(label, ...args); // save all triggerd labels for onready and onceready
|
||||||
|
let _trigger = (inListener, label, ...args) => {
|
||||||
|
let listeners = inListener.get(label);
|
||||||
|
if (listeners && listeners.length) {
|
||||||
|
listeners.forEach((listener) => {
|
||||||
|
|
||||||
|
listener(...args);
|
||||||
|
});
|
||||||
|
res = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
_trigger(this.onceListeners, label, ...args);
|
||||||
|
_trigger(this.listeners, label, ...args);
|
||||||
|
this.onceListeners.delete(label); // callback for once executed, so delete it.
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
dispose() {
|
||||||
|
for (var i = this.stackEvent.length - 1; i >= 0; i -= 1) {
|
||||||
|
var e = this.stackEvent[i];
|
||||||
|
e.element.removeEventListener(e.event, e.callback, false);
|
||||||
|
this.stackEvent.splice(i, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//this.stackEvent.push({ "event": "click", "callback": k, "element": c, "parent": null });
|
||||||
|
removeEvent(a) {
|
||||||
|
for (var i = this.stackEvent.length - 1; i >= 0; i -= 1) {
|
||||||
|
var e = this.stackEvent[i];
|
||||||
|
if (e.element == a) {
|
||||||
|
e.element.removeEventListener(e.event, e.callback, false);
|
||||||
|
this.stackEvent.splice(i, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
removeEventParent(a) {
|
||||||
|
for (var i = this.stackEvent.length - 1; i >= 0; i -= 1) {
|
||||||
|
var e = this.stackEvent[i];
|
||||||
|
if (e.parent == a) {
|
||||||
|
e.element.removeEventListener(e.event, e.callback, false);
|
||||||
|
this.stackEvent.splice(i, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
removeAllChildNodes(parent) {
|
||||||
|
while (parent.firstChild) {
|
||||||
|
parent.removeChild(parent.firstChild);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cloneNodes(elmS, elmD) {
|
||||||
|
var childs = elmS.childNodes;
|
||||||
|
for (var i = 0; i < childs.length; i++) {
|
||||||
|
elmD.appendChild(childs[i].cloneNode(true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class LoadScriptAsync extends window.AObject {
|
||||||
|
constructor(type) {
|
||||||
|
super();
|
||||||
|
this.type = type;
|
||||||
|
this.listCurrent = new Map();
|
||||||
|
this.stackScript = [];
|
||||||
|
this.jsLib = document.querySelector("section[app-js-lib]");
|
||||||
|
this.jsPage = document.querySelector("section[app-js-page]");
|
||||||
|
this.count = 0;
|
||||||
|
}
|
||||||
|
getScripts() {
|
||||||
|
document.querySelectorAll("section [js-lib]").forEach(el => {
|
||||||
|
|
||||||
|
if (!el.hasAttribute("checked")) {
|
||||||
|
this.listCurrent.set(el.src.split(/(\\|\/)/g).pop(), { "el": el.src, "status": "0" });
|
||||||
|
el.setAttribute("checked", "");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
processScript(doc) {
|
||||||
|
if (typeof doc.childNodes === "undefined") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.stackScript = [];
|
||||||
|
this.listCurrent = new Map();
|
||||||
|
this.getScripts();
|
||||||
|
for (var i = 0; i < doc.childNodes.length; i++) {
|
||||||
|
var n = doc.childNodes[i];
|
||||||
|
if (n.getAttribute("js-page") != null) {
|
||||||
|
this.stackScript.push({ "el": n });
|
||||||
|
}
|
||||||
|
if (n.getAttribute("js-lib") != null) {
|
||||||
|
if (this.checkExist(n)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var src = n.getAttribute("src");
|
||||||
|
this.jsLib.appendChild(this.createScriptTag(n));
|
||||||
|
this.listCurrent.set(src.split(/(\\|\/)/g).pop(), { "el": src, "status": "0" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.requestTimeout(this.checkLoaded.bind(this), 10, window.registerCancel);
|
||||||
|
}
|
||||||
|
checkLoaded(depend) {
|
||||||
|
this.listCurrent.forEach((v, k, m) => {
|
||||||
|
var tn = k.substring(0, k.length - 3);
|
||||||
|
if (window.AScript.has(tn)) {
|
||||||
|
this.listCurrent.delete(k);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (this.listCurrent.size == 0) {
|
||||||
|
this.addJsPage();
|
||||||
|
this.trigger("Loaded", null);
|
||||||
|
} else {
|
||||||
|
window.requestTimeout(this.checkLoaded.bind(this), 10, window.registerCancel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
checkExist(elm) {
|
||||||
|
if (this.listCurrent.has(elm.src.split(/(\\|\/)/g).pop())) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
createScriptTag(el) {
|
||||||
|
var newScript = document.createElement("script");
|
||||||
|
newScript.setAttribute("async", "");
|
||||||
|
for (var i = 0; i < el.attributes.length; i++) {
|
||||||
|
newScript.setAttribute(el.attributes[i].name, el.attributes[i].value);
|
||||||
|
}
|
||||||
|
if (!el.hasChildNodes()) {
|
||||||
|
newScript.src = el.src;
|
||||||
|
} else {
|
||||||
|
var tmp = document.createTextNode(el.innerHTML);
|
||||||
|
newScript.appendChild(tmp);
|
||||||
|
}
|
||||||
|
return newScript;
|
||||||
|
}
|
||||||
|
addJsPage() {
|
||||||
|
this.jsPage.innerHTML = "";
|
||||||
|
if (window.Destroy != undefined) window.Destroy();
|
||||||
|
this.stackScript.forEach(el => {
|
||||||
|
this.jsPage.appendChild(this.createScriptTag(el.el));
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class AApp extends window.AObject {
|
||||||
|
constructor(container = '[app-content]') {
|
||||||
|
super();
|
||||||
|
this.listScripts = [];
|
||||||
|
this.cachePage = [];
|
||||||
|
this.isLoadedLayout = false;
|
||||||
|
window.Destroy = undefined;
|
||||||
|
this.isRedirectPage = false;
|
||||||
|
var tmp = document.querySelector(container);
|
||||||
|
this.mainApp = tmp.querySelector("[main-content]") ? tmp.querySelector("[main-content]") : tmp;
|
||||||
|
var f = function (ev) {
|
||||||
|
if (ev.state) {
|
||||||
|
var temp = document.createElement("template");
|
||||||
|
temp.innerHTML = ev.state.html;
|
||||||
|
this.loadContentPage(temp.content);
|
||||||
|
document.head.querySelector("meta[name=idPage]").content = ev.state.idPage;
|
||||||
|
this.trigger("redirect_page", ev.state);
|
||||||
|
var l = new LoadScriptAsync("Page");
|
||||||
|
l.on("Loaded", () => {
|
||||||
|
this.loadedPage(false);
|
||||||
|
});
|
||||||
|
l.processScript(ev.state.doc);
|
||||||
|
}
|
||||||
|
}.bind(this);
|
||||||
|
window.addEventListener("popstate", f);
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
this.renderLayout();
|
||||||
|
this.renderNoLayout();
|
||||||
|
}
|
||||||
|
renderNoLayout() {
|
||||||
|
(function () {
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("GET", window.location.href + "?vr=cAsync");
|
||||||
|
xhr.send();
|
||||||
|
var f = function (evt) {
|
||||||
|
if (evt.currentTarget.readyState == 4 && evt.currentTarget.status == 200) {
|
||||||
|
if (evt.currentTarget.responseText) {
|
||||||
|
var jP = JSON.parse(evt.currentTarget.responseText);
|
||||||
|
this.loadPage(jP, window.location.href);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.bind(this);
|
||||||
|
xhr.addEventListener("readystatechange", f, false);
|
||||||
|
}).bind(this)();
|
||||||
|
}
|
||||||
|
renderLayout() {
|
||||||
|
(function () {
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("GET", window.location.href + "?vr=lAsync");
|
||||||
|
xhr.send();
|
||||||
|
var f = function (evt) {
|
||||||
|
if (evt.currentTarget.readyState == 4 && evt.currentTarget.status == 200) {
|
||||||
|
if (evt.currentTarget.responseText) {
|
||||||
|
var jP = JSON.parse(evt.currentTarget.responseText);
|
||||||
|
this.loadLayout(jP, window.location.href);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.bind(this);
|
||||||
|
xhr.addEventListener("readystatechange", f, false);
|
||||||
|
}).bind(this)();
|
||||||
|
}
|
||||||
|
loadedPage() {
|
||||||
|
var t = document.head.querySelector("meta[name=idPage]");
|
||||||
|
if (t != null && this.isLoadedLayout) {
|
||||||
|
if (window["L" + t.content] != null) {
|
||||||
|
window["L" + t.content]();
|
||||||
|
}
|
||||||
|
this.trigger("pageLoaded", null);
|
||||||
|
} else {
|
||||||
|
window.requestTimeout(this.loadedPage.bind(this), 10, window.registerCancel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
loadedLayout() {
|
||||||
|
if (!window.isLoad_Menu) {
|
||||||
|
window.Load_Menu();
|
||||||
|
this.isLoadedLayout = true;
|
||||||
|
}
|
||||||
|
this.trigger("layoutLoaded", null);
|
||||||
|
}
|
||||||
|
initScrollBar(callback = null) {
|
||||||
|
if (window.getOS() == "iOS") {
|
||||||
|
document.querySelector(".main-scrollbar[data-scrollbar]").classList.add("iOS");
|
||||||
|
let scrollY = 0;
|
||||||
|
let ticking = false;
|
||||||
|
|
||||||
|
window.addEventListener('scroll', (event) => {
|
||||||
|
scrollY = window.scrollY;
|
||||||
|
|
||||||
|
if (!ticking) {
|
||||||
|
window.requestAnimationFrame(() => {
|
||||||
|
callback ? callback.call(this, scrollY) : "";
|
||||||
|
ticking = false;
|
||||||
|
});
|
||||||
|
ticking = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
var sOption = {
|
||||||
|
damping: 0.2,
|
||||||
|
thumbMinSize: 25,
|
||||||
|
renderByPixel: true,
|
||||||
|
alwaysShowTracks: true,
|
||||||
|
continuousScrolling: true,
|
||||||
|
plugins: {
|
||||||
|
overscroll: {
|
||||||
|
effect: 'bounce',
|
||||||
|
damping: 0.15,
|
||||||
|
maxOverscroll: 250
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
window.smScroll = window.Scrollbar.init(document.querySelector('.main-scrollbar[data-scrollbar]'), sOption);
|
||||||
|
window.smScroll.addListener(status => {
|
||||||
|
callback ? callback.call(this, status.offset.y) : "";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
initNavApp(t) {
|
||||||
|
this.isRedirectPage = true;
|
||||||
|
this.callLoadPage(t.getAttribute("app-url"));
|
||||||
|
}
|
||||||
|
callLoadPage(url) {
|
||||||
|
var f = true;
|
||||||
|
var page = null;
|
||||||
|
for (var i = 0; i < this.cachePage.length; i++) {
|
||||||
|
if (this.cachePage[i].src == url) {
|
||||||
|
f = false;
|
||||||
|
page = this.cachePage[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (f) {
|
||||||
|
this.getPage(url);
|
||||||
|
} else {
|
||||||
|
var tpl = document.createElement('template');
|
||||||
|
tpl.innerHTML = page.html;
|
||||||
|
this.setContentPage(Object.assign({}, page, { "html": tpl.content }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
loadContentPage(content) {
|
||||||
|
for (var i = this.mainApp.childNodes.length - 1; i >= 0; i--) {
|
||||||
|
this.mainApp.childNodes[i].remove();
|
||||||
|
}
|
||||||
|
this.mainApp.appendChild(content);
|
||||||
|
}
|
||||||
|
setContentPage(page) {
|
||||||
|
document.title = page.title + " - ATG Management System";
|
||||||
|
document.head.querySelector("meta[name=idPage]").content = page.idPage;
|
||||||
|
this.loadContentPage(page.html);
|
||||||
|
window.history.pushState({ "html": this.mainApp.innerHTML, "doc": page.doc.innerHTML, "idPage": page.idPage }, page.title + " - ATG Management System", page.src);
|
||||||
|
var l = new LoadScriptAsync("Page");
|
||||||
|
if (this.isRedirectPage) {
|
||||||
|
this.trigger("redirect_page", page);
|
||||||
|
this.isRedirectPage = false;
|
||||||
|
}
|
||||||
|
l.on("Loaded", () => {
|
||||||
|
this.loadedPage(false);
|
||||||
|
});
|
||||||
|
l.processScript(page.doc);
|
||||||
|
|
||||||
|
}
|
||||||
|
getPage(url) {
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("GET", url + "?vr=cAsync");
|
||||||
|
xhr.send();
|
||||||
|
var f = function (evt) {
|
||||||
|
if (evt.currentTarget.readyState == 4 && evt.currentTarget.status == 200) {
|
||||||
|
if (evt.currentTarget.responseText) {
|
||||||
|
var jP = JSON.parse(evt.currentTarget.responseText);
|
||||||
|
this.loadPage(jP, url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.bind(this);
|
||||||
|
xhr.addEventListener("readystatechange", f, false);
|
||||||
|
}
|
||||||
|
loadLayout(o, url) {
|
||||||
|
var oP = new DOMParser();
|
||||||
|
var pHtml = oP.parseFromString(o.HTMLLayout, 'text/html');
|
||||||
|
(function () {
|
||||||
|
pHtml.body.childNodes.forEach(function (item) {
|
||||||
|
var t = document.getElementById(item.getAttribute("id"));
|
||||||
|
if (t) {
|
||||||
|
item.classList.forEach(el => {
|
||||||
|
t.classList.add(el);
|
||||||
|
});
|
||||||
|
item.childNodes.forEach(el => {
|
||||||
|
t.appendChild(el.cloneNode(true));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}).bind(this)();
|
||||||
|
(function () {
|
||||||
|
var doc = oP.parseFromString(o.ScriptsLayout, 'text/html').head;
|
||||||
|
var l = new LoadScriptAsync("Layout");
|
||||||
|
l.on("Loaded", () => {
|
||||||
|
this.loadedLayout();
|
||||||
|
});
|
||||||
|
l.processScript(doc);
|
||||||
|
}).bind(this)();
|
||||||
|
}
|
||||||
|
loadPage(o, url) {
|
||||||
|
var title = o.Title;
|
||||||
|
var idPage = o.PageId;
|
||||||
|
var tpl = document.createElement('template');
|
||||||
|
tpl.innerHTML = o.HTMLContent;
|
||||||
|
var doc2 = new DOMParser().parseFromString(o.Scripts, "text/html");
|
||||||
|
var obj = { "src": url, "html": o.HTMLContent, "title": title, "idPage": idPage, "doc": doc2.firstChild.querySelector("head") };
|
||||||
|
this.cachePage.push(obj);
|
||||||
|
this.setContentPage(Object.assign({}, obj, { "html": tpl.content }));
|
||||||
|
}
|
||||||
|
loadCSS(arr) {
|
||||||
|
for (var i = 0; i < arr.length; i++) {
|
||||||
|
var link = document.createElement('link');
|
||||||
|
link.setAttribute('rel', 'stylesheet');
|
||||||
|
link.setAttribute('href', arr[i]);
|
||||||
|
document.head.appendChild(link);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.removeStopCollapsed = function () {
|
||||||
|
if (window.dropdown != null && window.dropdown.currentE != null) {
|
||||||
|
if (window.dropdown.currentE.item.hasAttribute("stopCollapsed")) {
|
||||||
|
window.dropdown.currentE.item.removeAttribute("stopCollapsed");
|
||||||
|
window.dropdown.currentE = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
window.scroll_options = {
|
||||||
|
damping: 0.1,
|
||||||
|
thumbMinSize: 25,
|
||||||
|
renderByPixel: true,
|
||||||
|
alwaysShowTracks: true,
|
||||||
|
continuousScrolling: true,
|
||||||
|
plugins: {
|
||||||
|
overscroll: {
|
||||||
|
effect: 'bounce',
|
||||||
|
damping: 0.15,
|
||||||
|
maxOverscroll: 150
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
75
AppLibs/AppLibs/wwwroot/js/libs/js-upload-worker.js
Normal file
75
AppLibs/AppLibs/wwwroot/js/libs/js-upload-worker.js
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
var requestInterval = function (fn, delay) {
|
||||||
|
if (!self.requestAnimationFrame &&
|
||||||
|
!self.webkitRequestAnimationFrame &&
|
||||||
|
!(self.mozRequestAnimationFrame && self.mozCancelRequestAnimationFrame) && // Firefox 5 ships without cancel support
|
||||||
|
!self.oRequestAnimationFrame &&
|
||||||
|
!self.msRequestAnimationFrame)
|
||||||
|
return self.setInterval(fn, delay);
|
||||||
|
|
||||||
|
var start = new Date().getTime(),
|
||||||
|
handle = new Object();
|
||||||
|
|
||||||
|
function loop() {
|
||||||
|
var current = new Date().getTime(),
|
||||||
|
delta = current - start;
|
||||||
|
|
||||||
|
if (delta >= delay) {
|
||||||
|
fn.call();
|
||||||
|
start = new Date().getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
handle.value = self.requestAnimationFrame(loop);
|
||||||
|
};
|
||||||
|
|
||||||
|
handle.value = self.requestAnimationFrame(loop);
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
var clearRequestInterval = function (handle) {
|
||||||
|
self.cancelAnimationFrame ? self.cancelAnimationFrame(handle.value) :
|
||||||
|
self.webkitCancelAnimationFrame ? self.webkitCancelAnimationFrame(handle.value) :
|
||||||
|
self.webkitCancelRequestAnimationFrame ? self.webkitCancelRequestAnimationFrame(handle.value) : /* Support for legacy API */
|
||||||
|
self.mozCancelRequestAnimationFrame ? self.mozCancelRequestAnimationFrame(handle.value) :
|
||||||
|
self.oCancelRequestAnimationFrame ? self.oCancelRequestAnimationFrame(handle.value) :
|
||||||
|
self.msCancelRequestAnimationFrame ? self.msCancelRequestAnimationFrame(handle.value) :
|
||||||
|
clearInterval(handle);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var lpPop;
|
||||||
|
var request;
|
||||||
|
var count = 0;
|
||||||
|
var f = function (e) {
|
||||||
|
if (e.data != null) {
|
||||||
|
if (e.data.status == "StartUpload") {
|
||||||
|
request = e.data.totalF;
|
||||||
|
}
|
||||||
|
else if (e.data.status == "Uploaded")
|
||||||
|
{
|
||||||
|
var b = e.data.bucket;
|
||||||
|
var flag = true;
|
||||||
|
for (var i = 0; i < b.length; i++) {
|
||||||
|
if (b[i] == 0) {
|
||||||
|
flag = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (flag) {
|
||||||
|
count += b.length;
|
||||||
|
if (count == request) {
|
||||||
|
self.postMessage("Uploaded");
|
||||||
|
lpPop = requestInterval(function() {
|
||||||
|
self.postMessage("Tick");
|
||||||
|
}, 500);
|
||||||
|
} else {
|
||||||
|
self.postMessage("Upload");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (e.data.status == "NoItem")
|
||||||
|
{
|
||||||
|
clearRequestInterval(lpPop);
|
||||||
|
self.postMessage("Finish");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.addEventListener("message", f, false);
|
||||||
|
|
1049
AppLibs/AppLibs/wwwroot/js/libs/js-upload.js
Normal file
1049
AppLibs/AppLibs/wwwroot/js/libs/js-upload.js
Normal file
File diff suppressed because it is too large
Load Diff
537
AppLibs/AppLibs/wwwroot/js/libs/js-waves.js
Normal file
537
AppLibs/AppLibs/wwwroot/js/libs/js-waves.js
Normal file
@ -0,0 +1,537 @@
|
|||||||
|
/*!
|
||||||
|
* Waves v0.7.6
|
||||||
|
* http://fian.my.id/Waves
|
||||||
|
*
|
||||||
|
* Copyright 2014-2018 Alfiana E. Sibuea and other contributors
|
||||||
|
* Released under the MIT license
|
||||||
|
* https://github.com/fians/Waves/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
;(function(window, factory) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
// AMD. Register as an anonymous module. Wrap in function so we have access
|
||||||
|
// to root via `this`.
|
||||||
|
if (typeof define === 'function' && define.amd) {
|
||||||
|
define([], function() {
|
||||||
|
window.Waves = factory.call(window);
|
||||||
|
return window.Waves;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Node. Does not work with strict CommonJS, but only CommonJS-like
|
||||||
|
// environments that support module.exports, like Node.
|
||||||
|
else if (typeof exports === 'object') {
|
||||||
|
module.exports = factory.call(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Browser globals.
|
||||||
|
else {
|
||||||
|
window.Waves = factory.call(window);
|
||||||
|
}
|
||||||
|
})(typeof global === 'object' ? global : this, function() {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var Waves = Waves || {};
|
||||||
|
var $$ = document.querySelectorAll.bind(document);
|
||||||
|
var toString = Object.prototype.toString;
|
||||||
|
var isTouchAvailable = 'ontouchstart' in window;
|
||||||
|
|
||||||
|
|
||||||
|
// Find exact position of element
|
||||||
|
function isWindow(obj) {
|
||||||
|
return obj !== null && obj === obj.window;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getWindow(elem) {
|
||||||
|
return isWindow(elem) ? elem : elem.nodeType === 9 && elem.defaultView;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isObject(value) {
|
||||||
|
var type = typeof value;
|
||||||
|
return type === 'function' || type === 'object' && !!value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isDOMNode(obj) {
|
||||||
|
return isObject(obj) && obj.nodeType > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getWavesElements(nodes) {
|
||||||
|
var stringRepr = toString.call(nodes);
|
||||||
|
|
||||||
|
if (stringRepr === '[object String]') {
|
||||||
|
return $$(nodes);
|
||||||
|
} else if (isObject(nodes) && /^\[object (Array|HTMLCollection|NodeList|Object)\]$/.test(stringRepr) && nodes.hasOwnProperty('length')) {
|
||||||
|
return nodes;
|
||||||
|
} else if (isDOMNode(nodes)) {
|
||||||
|
return [nodes];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
function offset(elem) {
|
||||||
|
var docElem, win,
|
||||||
|
box = { top: 0, left: 0 },
|
||||||
|
doc = elem && elem.ownerDocument;
|
||||||
|
|
||||||
|
docElem = doc.documentElement;
|
||||||
|
|
||||||
|
if (typeof elem.getBoundingClientRect !== typeof undefined) {
|
||||||
|
box = elem.getBoundingClientRect();
|
||||||
|
}
|
||||||
|
win = getWindow(doc);
|
||||||
|
return {
|
||||||
|
top: box.top + win.pageYOffset - docElem.clientTop,
|
||||||
|
left: box.left + win.pageXOffset - docElem.clientLeft
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function convertStyle(styleObj) {
|
||||||
|
var style = '';
|
||||||
|
|
||||||
|
for (var prop in styleObj) {
|
||||||
|
if (styleObj.hasOwnProperty(prop)) {
|
||||||
|
style += (prop + ':' + styleObj[prop] + ';');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return style;
|
||||||
|
}
|
||||||
|
|
||||||
|
var Effect = {
|
||||||
|
|
||||||
|
// Effect duration
|
||||||
|
duration: 750,
|
||||||
|
|
||||||
|
// Effect delay (check for scroll before showing effect)
|
||||||
|
delay: 200,
|
||||||
|
|
||||||
|
show: function(e, element, velocity) {
|
||||||
|
|
||||||
|
// Disable right click
|
||||||
|
if (e.button === 2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
element = element || this;
|
||||||
|
|
||||||
|
// Create ripple
|
||||||
|
var ripple = document.createElement('div');
|
||||||
|
ripple.className = 'waves-ripple waves-rippling';
|
||||||
|
element.appendChild(ripple);
|
||||||
|
|
||||||
|
// Get click coordinate and element width
|
||||||
|
var pos = offset(element);
|
||||||
|
var relativeY = 0;
|
||||||
|
var relativeX = 0;
|
||||||
|
// Support for touch devices
|
||||||
|
if('touches' in e && e.touches.length) {
|
||||||
|
relativeY = (e.touches[0].pageY - pos.top);
|
||||||
|
relativeX = (e.touches[0].pageX - pos.left);
|
||||||
|
}
|
||||||
|
//Normal case
|
||||||
|
else {
|
||||||
|
relativeY = (e.pageY - pos.top);
|
||||||
|
relativeX = (e.pageX - pos.left);
|
||||||
|
}
|
||||||
|
// Support for synthetic events
|
||||||
|
relativeX = relativeX >= 0 ? relativeX : 0;
|
||||||
|
relativeY = relativeY >= 0 ? relativeY : 0;
|
||||||
|
|
||||||
|
var scale = 'scale(' + ((element.clientWidth / 100) * 3) + ')';
|
||||||
|
var translate = 'translate(0,0)';
|
||||||
|
|
||||||
|
if (velocity) {
|
||||||
|
translate = 'translate(' + (velocity.x) + 'px, ' + (velocity.y) + 'px)';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attach data to element
|
||||||
|
ripple.setAttribute('data-hold', Date.now());
|
||||||
|
ripple.setAttribute('data-x', relativeX);
|
||||||
|
ripple.setAttribute('data-y', relativeY);
|
||||||
|
ripple.setAttribute('data-scale', scale);
|
||||||
|
ripple.setAttribute('data-translate', translate);
|
||||||
|
|
||||||
|
// Set ripple position
|
||||||
|
var rippleStyle = {
|
||||||
|
top: relativeY + 'px',
|
||||||
|
left: relativeX + 'px'
|
||||||
|
};
|
||||||
|
|
||||||
|
ripple.classList.add('waves-notransition');
|
||||||
|
ripple.setAttribute('style', convertStyle(rippleStyle));
|
||||||
|
ripple.classList.remove('waves-notransition');
|
||||||
|
|
||||||
|
// Scale the ripple
|
||||||
|
rippleStyle['-webkit-transform'] = scale + ' ' + translate;
|
||||||
|
rippleStyle['-moz-transform'] = scale + ' ' + translate;
|
||||||
|
rippleStyle['-ms-transform'] = scale + ' ' + translate;
|
||||||
|
rippleStyle['-o-transform'] = scale + ' ' + translate;
|
||||||
|
rippleStyle.transform = scale + ' ' + translate;
|
||||||
|
rippleStyle.opacity = '1';
|
||||||
|
|
||||||
|
var duration = e.type === 'mousemove' ? 2500 : Effect.duration;
|
||||||
|
rippleStyle['-webkit-transition-duration'] = duration + 'ms';
|
||||||
|
rippleStyle['-moz-transition-duration'] = duration + 'ms';
|
||||||
|
rippleStyle['-o-transition-duration'] = duration + 'ms';
|
||||||
|
rippleStyle['transition-duration'] = duration + 'ms';
|
||||||
|
|
||||||
|
ripple.setAttribute('style', convertStyle(rippleStyle));
|
||||||
|
},
|
||||||
|
|
||||||
|
hide: function(e, element) {
|
||||||
|
element = element || this;
|
||||||
|
|
||||||
|
var ripples = element.getElementsByClassName('waves-rippling');
|
||||||
|
|
||||||
|
for (var i = 0, len = ripples.length; i < len; i++) {
|
||||||
|
removeRipple(e, element, ripples[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isTouchAvailable) {
|
||||||
|
element.removeEventListener('touchend', Effect.hide);
|
||||||
|
element.removeEventListener('touchcancel', Effect.hide);
|
||||||
|
}
|
||||||
|
|
||||||
|
element.removeEventListener('mouseup', Effect.hide);
|
||||||
|
element.removeEventListener('mouseleave', Effect.hide);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collection of wrapper for HTML element that only have single tag
|
||||||
|
* like <input> and <img>
|
||||||
|
*/
|
||||||
|
var TagWrapper = {
|
||||||
|
|
||||||
|
// Wrap <input> tag so it can perform the effect
|
||||||
|
input: function(element) {
|
||||||
|
|
||||||
|
var parent = element.parentNode;
|
||||||
|
|
||||||
|
// If input already have parent just pass through
|
||||||
|
if (parent.tagName.toLowerCase() === 'i' && parent.classList.contains('waves-effect')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put element class and style to the specified parent
|
||||||
|
var wrapper = document.createElement('i');
|
||||||
|
wrapper.className = element.className + ' waves-input-wrapper';
|
||||||
|
element.className = 'waves-button-input';
|
||||||
|
|
||||||
|
// Put element as child
|
||||||
|
parent.replaceChild(wrapper, element);
|
||||||
|
wrapper.appendChild(element);
|
||||||
|
|
||||||
|
// Apply element color and background color to wrapper
|
||||||
|
var elementStyle = window.getComputedStyle(element, null);
|
||||||
|
var color = elementStyle.color;
|
||||||
|
var backgroundColor = elementStyle.backgroundColor;
|
||||||
|
|
||||||
|
wrapper.setAttribute('style', 'color:' + color + ';background:' + backgroundColor);
|
||||||
|
element.setAttribute('style', 'background-color:rgba(0,0,0,0);');
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
// Wrap <img> tag so it can perform the effect
|
||||||
|
img: function(element) {
|
||||||
|
|
||||||
|
var parent = element.parentNode;
|
||||||
|
|
||||||
|
// If input already have parent just pass through
|
||||||
|
if (parent.tagName.toLowerCase() === 'i' && parent.classList.contains('waves-effect')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put element as child
|
||||||
|
var wrapper = document.createElement('i');
|
||||||
|
parent.replaceChild(wrapper, element);
|
||||||
|
wrapper.appendChild(element);
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hide the effect and remove the ripple. Must be
|
||||||
|
* a separate function to pass the JSLint...
|
||||||
|
*/
|
||||||
|
function removeRipple(e, el, ripple) {
|
||||||
|
|
||||||
|
// Check if the ripple still exist
|
||||||
|
if (!ripple) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ripple.classList.remove('waves-rippling');
|
||||||
|
|
||||||
|
var relativeX = ripple.getAttribute('data-x');
|
||||||
|
var relativeY = ripple.getAttribute('data-y');
|
||||||
|
var scale = ripple.getAttribute('data-scale');
|
||||||
|
var translate = ripple.getAttribute('data-translate');
|
||||||
|
|
||||||
|
// Get delay beetween mousedown and mouse leave
|
||||||
|
var diff = Date.now() - Number(ripple.getAttribute('data-hold'));
|
||||||
|
var delay = 350 - diff;
|
||||||
|
|
||||||
|
if (delay < 0) {
|
||||||
|
delay = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.type === 'mousemove') {
|
||||||
|
delay = 150;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fade out ripple after delay
|
||||||
|
var duration = e.type === 'mousemove' ? 2500 : Effect.duration;
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
|
||||||
|
var style = {
|
||||||
|
top: relativeY + 'px',
|
||||||
|
left: relativeX + 'px',
|
||||||
|
opacity: '0',
|
||||||
|
|
||||||
|
// Duration
|
||||||
|
'-webkit-transition-duration': duration + 'ms',
|
||||||
|
'-moz-transition-duration': duration + 'ms',
|
||||||
|
'-o-transition-duration': duration + 'ms',
|
||||||
|
'transition-duration': duration + 'ms',
|
||||||
|
'-webkit-transform': scale + ' ' + translate,
|
||||||
|
'-moz-transform': scale + ' ' + translate,
|
||||||
|
'-ms-transform': scale + ' ' + translate,
|
||||||
|
'-o-transform': scale + ' ' + translate,
|
||||||
|
'transform': scale + ' ' + translate
|
||||||
|
};
|
||||||
|
|
||||||
|
ripple.setAttribute('style', convertStyle(style));
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
try {
|
||||||
|
el.removeChild(ripple);
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}, duration);
|
||||||
|
|
||||||
|
}, delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disable mousedown event for 500ms during and after touch
|
||||||
|
*/
|
||||||
|
var TouchHandler = {
|
||||||
|
|
||||||
|
/* uses an integer rather than bool so there's no issues with
|
||||||
|
* needing to clear timeouts if another touch event occurred
|
||||||
|
* within the 500ms. Cannot mouseup between touchstart and
|
||||||
|
* touchend, nor in the 500ms after touchend. */
|
||||||
|
touches: 0,
|
||||||
|
|
||||||
|
allowEvent: function(e) {
|
||||||
|
var allow = true;
|
||||||
|
if (/^(mousedown|mousemove)$/.test(e.type) && TouchHandler.touches) {
|
||||||
|
allow = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return allow;
|
||||||
|
},
|
||||||
|
registerEvent: function(e) {
|
||||||
|
var eType = e.type;
|
||||||
|
|
||||||
|
if (eType === 'touchstart') {
|
||||||
|
|
||||||
|
TouchHandler.touches += 1; // push
|
||||||
|
|
||||||
|
} else if (/^(touchend|touchcancel)$/.test(eType)) {
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
if (TouchHandler.touches) {
|
||||||
|
TouchHandler.touches -= 1; // pop after 500ms
|
||||||
|
}
|
||||||
|
}, 500);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delegated click handler for .waves-effect element.
|
||||||
|
* returns null when .waves-effect element not in "click tree"
|
||||||
|
*/
|
||||||
|
function getWavesEffectElement(e) {
|
||||||
|
|
||||||
|
if (TouchHandler.allowEvent(e) === false) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var element = null;
|
||||||
|
var target = e.target || e.srcElement;
|
||||||
|
|
||||||
|
while (target.parentElement) {
|
||||||
|
if ( (!(target instanceof SVGElement)) && target.classList.contains('waves-effect')) {
|
||||||
|
element = target;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
target = target.parentElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bubble the click and show effect if .waves-effect elem was found
|
||||||
|
*/
|
||||||
|
function showEffect(e) {
|
||||||
|
|
||||||
|
// Disable effect if element has "disabled" property on it
|
||||||
|
// In some cases, the event is not triggered by the current element
|
||||||
|
// if (e.target.getAttribute('disabled') !== null) {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
var element = getWavesEffectElement(e);
|
||||||
|
if (element !== null) {
|
||||||
|
|
||||||
|
// Make it sure the element has either disabled property, disabled attribute or 'disabled' class
|
||||||
|
if (element.disabled || element.getAttribute('disabled') || element.classList.contains('disabled')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TouchHandler.registerEvent(e);
|
||||||
|
|
||||||
|
if (e.type === 'touchstart' && Effect.delay) {
|
||||||
|
|
||||||
|
var hidden = false;
|
||||||
|
|
||||||
|
var timer = setTimeout(function () {
|
||||||
|
timer = null;
|
||||||
|
Effect.show(e, element);
|
||||||
|
}, Effect.delay);
|
||||||
|
|
||||||
|
var hideEffect = function(hideEvent) {
|
||||||
|
|
||||||
|
// if touch hasn't moved, and effect not yet started: start effect now
|
||||||
|
if (timer) {
|
||||||
|
clearTimeout(timer);
|
||||||
|
timer = null;
|
||||||
|
Effect.show(e, element);
|
||||||
|
}
|
||||||
|
if (!hidden) {
|
||||||
|
hidden = true;
|
||||||
|
Effect.hide(hideEvent, element);
|
||||||
|
}
|
||||||
|
|
||||||
|
removeListeners();
|
||||||
|
};
|
||||||
|
|
||||||
|
var touchMove = function(moveEvent) {
|
||||||
|
if (timer) {
|
||||||
|
clearTimeout(timer);
|
||||||
|
timer = null;
|
||||||
|
}
|
||||||
|
hideEffect(moveEvent);
|
||||||
|
|
||||||
|
removeListeners();
|
||||||
|
};
|
||||||
|
|
||||||
|
element.addEventListener('touchmove', touchMove, false);
|
||||||
|
element.addEventListener('touchend', hideEffect, false);
|
||||||
|
element.addEventListener('touchcancel', hideEffect, false);
|
||||||
|
|
||||||
|
var removeListeners = function() {
|
||||||
|
element.removeEventListener('touchmove', touchMove);
|
||||||
|
element.removeEventListener('touchend', hideEffect);
|
||||||
|
element.removeEventListener('touchcancel', hideEffect);
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
|
||||||
|
Effect.show(e, element);
|
||||||
|
|
||||||
|
if (isTouchAvailable) {
|
||||||
|
element.addEventListener('touchend', Effect.hide, false);
|
||||||
|
element.addEventListener('touchcancel', Effect.hide, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
element.addEventListener('mouseup', Effect.hide, false);
|
||||||
|
element.addEventListener('mouseleave', Effect.hide, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Waves.init = function(options) {
|
||||||
|
var body = document.body;
|
||||||
|
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
|
if ('duration' in options) {
|
||||||
|
Effect.duration = options.duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('delay' in options) {
|
||||||
|
Effect.delay = options.delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isTouchAvailable) {
|
||||||
|
body.addEventListener('touchstart', showEffect, false);
|
||||||
|
body.addEventListener('touchcancel', TouchHandler.registerEvent, false);
|
||||||
|
body.addEventListener('touchend', TouchHandler.registerEvent, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
body.addEventListener('mousedown', showEffect, false);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attach Waves to dynamically loaded inputs, or add .waves-effect and other
|
||||||
|
* waves classes to a set of elements. Set drag to true if the ripple mouseover
|
||||||
|
* or skimming effect should be applied to the elements.
|
||||||
|
*/
|
||||||
|
Waves.attach = function(elements, classes) {
|
||||||
|
|
||||||
|
elements = getWavesElements(elements);
|
||||||
|
|
||||||
|
if (toString.call(classes) === '[object Array]') {
|
||||||
|
classes = classes.join(' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
classes = classes ? ' ' + classes : '';
|
||||||
|
|
||||||
|
var element, tagName;
|
||||||
|
|
||||||
|
for (var i = 0, len = elements.length; i < len; i++) {
|
||||||
|
|
||||||
|
element = elements[i];
|
||||||
|
tagName = element.tagName.toLowerCase();
|
||||||
|
|
||||||
|
if (['input', 'img'].indexOf(tagName) !== -1) {
|
||||||
|
TagWrapper[tagName](element);
|
||||||
|
element = element.parentElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (element.className.indexOf('waves-effect') === -1) {
|
||||||
|
element.className += ' waves-effect' + classes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove all ripples from an element.
|
||||||
|
*/
|
||||||
|
Waves.calm = function(elements) {
|
||||||
|
elements = getWavesElements(elements);
|
||||||
|
var mouseup = {
|
||||||
|
type: 'mouseup',
|
||||||
|
button: 1
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var i = 0, len = elements.length; i < len; i++) {
|
||||||
|
Effect.hide(mouseup, elements[i]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return Waves;
|
||||||
|
});
|
||||||
|
|
||||||
|
window.AScript.set("js-waves", true);
|
1
AppLibs/AppLibs/wwwroot/js/libs/js-waves.min.js
vendored
Normal file
1
AppLibs/AppLibs/wwwroot/js/libs/js-waves.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
AppLibs/AppLibs/wwwroot/js/libs/js-waves.min.js.map
Normal file
1
AppLibs/AppLibs/wwwroot/js/libs/js-waves.min.js.map
Normal file
File diff suppressed because one or more lines are too long
BIN
Database Diagram/db.mwb
Normal file
BIN
Database Diagram/db.mwb
Normal file
Binary file not shown.
BIN
Database Diagram/db.mwb.bak
Normal file
BIN
Database Diagram/db.mwb.bak
Normal file
Binary file not shown.
12
ManagementApp/.config/dotnet-tools.json
Normal file
12
ManagementApp/.config/dotnet-tools.json
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"isRoot": true,
|
||||||
|
"tools": {
|
||||||
|
"dotnet-ef": {
|
||||||
|
"version": "8.0.6",
|
||||||
|
"commands": [
|
||||||
|
"dotnet-ef"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
6
ManagementApp/AServices/Microsoft365/IMicrosoft365.cs
Normal file
6
ManagementApp/AServices/Microsoft365/IMicrosoft365.cs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
namespace ManagementApp.AServices.Microsoft365
|
||||||
|
{
|
||||||
|
public interface IMicrosoft365
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
11
ManagementApp/AServices/Microsoft365/Microsoft365.cs
Normal file
11
ManagementApp/AServices/Microsoft365/Microsoft365.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
namespace ManagementApp.AServices.Microsoft365
|
||||||
|
{
|
||||||
|
public class Microsoft365: IMicrosoft365
|
||||||
|
{
|
||||||
|
public Microsoft365()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
11
ManagementApp/AServices/Microsoft365/Microsoft365Options.cs
Normal file
11
ManagementApp/AServices/Microsoft365/Microsoft365Options.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
namespace ManagementApp.AServices.Microsoft365
|
||||||
|
{
|
||||||
|
public class Microsoft365Options
|
||||||
|
{
|
||||||
|
public string TenantID { set; get; } = "";
|
||||||
|
public string ClientID { set; get; } = "";
|
||||||
|
|
||||||
|
public string SecretValue { set; get; } = "";
|
||||||
|
public string SecretID { set; get; } = "";
|
||||||
|
}
|
||||||
|
}
|
6
ManagementApp/AServices/Microsoft365/SharePointOption.cs
Normal file
6
ManagementApp/AServices/Microsoft365/SharePointOption.cs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
namespace ManagementApp.AServices.Microsoft365
|
||||||
|
{
|
||||||
|
public class SharePointOption
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
49
ManagementApp/AServices/Microsoft365Service.cs
Normal file
49
ManagementApp/AServices/Microsoft365Service.cs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
using ManagementApp.AServices.Microsoft365;
|
||||||
|
using ManagementApp.AServices.ThreadManage;
|
||||||
|
using Microsoft.Identity.Web;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
|
||||||
|
namespace ManagementApp.AServices
|
||||||
|
{
|
||||||
|
public class Microsoft365Service : BackgroundService, IDisposable
|
||||||
|
{
|
||||||
|
|
||||||
|
private readonly IConcurrentTasks _task;
|
||||||
|
public Microsoft365Service(IConcurrentTasks tasks) {
|
||||||
|
_task = tasks;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||||
|
{
|
||||||
|
await DoWork(stoppingToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task DoWork(CancellationToken stoppingToken)
|
||||||
|
{
|
||||||
|
while (!stoppingToken.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
var workItem = await _task.First(stoppingToken);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await workItem(stoppingToken);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task StopAsync(CancellationToken stoppingToken)
|
||||||
|
{
|
||||||
|
await base.StopAsync(stoppingToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Dispose()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
|
||||||
|
using Microsoft.AspNetCore.DataProtection.KeyManagement;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
|
||||||
|
namespace ManagementApp.AServices.ThreadManage
|
||||||
|
{
|
||||||
|
|
||||||
|
public class ConcurrentDictionaryThread<T>: IConcurrentTasks<T>, IConcurrentTasks
|
||||||
|
{
|
||||||
|
|
||||||
|
private readonly ConcurrentDictionary<T, Func<CancellationToken, ValueTask>> listTask;
|
||||||
|
public ConcurrentDictionaryThread() {
|
||||||
|
this.listTask = new ConcurrentDictionary<T, Func<CancellationToken, ValueTask>> ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async ValueTask Add(Func<CancellationToken, ValueTask> value)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
public async ValueTask<bool> Add(T key, Func<CancellationToken, ValueTask> value)
|
||||||
|
{
|
||||||
|
return await Task<bool>.Run(() => {
|
||||||
|
return listTask.TryAdd(key, value);
|
||||||
|
}) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async ValueTask<Func<CancellationToken, ValueTask>> Last(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
return await Task<Func<CancellationToken, ValueTask>>.Run(() => {
|
||||||
|
var d = listTask.Last();
|
||||||
|
listTask.TryRemove(d);
|
||||||
|
return d.Value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public async ValueTask<Func<CancellationToken, ValueTask>> First(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
return await Task<Func<CancellationToken, ValueTask>>.Run(() => {
|
||||||
|
var d = listTask.First();
|
||||||
|
listTask.TryRemove(d);
|
||||||
|
return d.Value;
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public async ValueTask<Func<CancellationToken, ValueTask>> Search(T key, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async ValueTask<Func<CancellationToken, ValueTask>> Update(T key, CancellationToken cancellationToken, Func<CancellationToken, ValueTask> value)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
using Microsoft.AspNetCore.Razor.Language.Intermediate;
|
||||||
|
using System.Threading.Channels;
|
||||||
|
|
||||||
|
namespace ManagementApp.AServices.ThreadManage
|
||||||
|
{
|
||||||
|
public class ConcurrentQueueThread: IConcurrentTasks
|
||||||
|
{
|
||||||
|
private readonly Channel<Func<CancellationToken, ValueTask>> queue;
|
||||||
|
public ConcurrentQueueThread(int capacity) {
|
||||||
|
var options = new BoundedChannelOptions(capacity)
|
||||||
|
{
|
||||||
|
FullMode = BoundedChannelFullMode.Wait
|
||||||
|
};
|
||||||
|
queue = Channel.CreateBounded<Func<CancellationToken, ValueTask>>(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async ValueTask Add(Func<CancellationToken, ValueTask> value)
|
||||||
|
{
|
||||||
|
await queue.Writer.WriteAsync(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async ValueTask<Func<CancellationToken, ValueTask>> Last(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async ValueTask<Func<CancellationToken, ValueTask>> First(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
|
||||||
|
return await queue.Reader.ReadAsync(cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
21
ManagementApp/AServices/ThreadManage/IConcurrentTasks.cs
Normal file
21
ManagementApp/AServices/ThreadManage/IConcurrentTasks.cs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
namespace ManagementApp.AServices.ThreadManage
|
||||||
|
{
|
||||||
|
public interface IConcurrentTasks<T>
|
||||||
|
{
|
||||||
|
ValueTask Add(Func<CancellationToken, ValueTask> value);
|
||||||
|
|
||||||
|
ValueTask<Func<CancellationToken, ValueTask>> Search(T key, CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
ValueTask<Func<CancellationToken, ValueTask>> Update(T key, CancellationToken cancellationToken, Func<CancellationToken, ValueTask> value);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IConcurrentTasks
|
||||||
|
{
|
||||||
|
ValueTask Add(Func<CancellationToken, ValueTask> value);
|
||||||
|
ValueTask<Func<CancellationToken, ValueTask>> Last(CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
ValueTask<Func<CancellationToken, ValueTask>> First(CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
28
ManagementApp/Controllers/HomeController.cs
Normal file
28
ManagementApp/Controllers/HomeController.cs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
using AppLibs.Libs;
|
||||||
|
using ManagementApp.Models;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace ManagementApp.Controllers
|
||||||
|
{
|
||||||
|
public class HomeController : Controller
|
||||||
|
{
|
||||||
|
private readonly ILogger<HomeController> _logger;
|
||||||
|
|
||||||
|
public HomeController(ILogger<HomeController> logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
[PageInfor("1000", "Home")]
|
||||||
|
public Task<IActionResult> Index()
|
||||||
|
{
|
||||||
|
return this.ViewAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IActionResult Privacy()
|
||||||
|
{
|
||||||
|
return View();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
25
ManagementApp/Controllers/RoomsController.cs
Normal file
25
ManagementApp/Controllers/RoomsController.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
using AppLibs.Libs;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace ManagementApp.Controllers
|
||||||
|
{
|
||||||
|
public class RoomsController : Controller
|
||||||
|
{
|
||||||
|
[PageInfor("8102", "Room List")]
|
||||||
|
public Task<IActionResult> Index()
|
||||||
|
{
|
||||||
|
return this.ViewAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
[PageInfor("8103", "Room List")]
|
||||||
|
public Task<IActionResult> RoomType()
|
||||||
|
{
|
||||||
|
return this.ViewAsync();
|
||||||
|
}
|
||||||
|
[PageInfor("8101", "Room List")]
|
||||||
|
public Task<IActionResult> Add()
|
||||||
|
{
|
||||||
|
return this.ViewAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
166
ManagementApp/Controllers/StorageController.cs
Normal file
166
ManagementApp/Controllers/StorageController.cs
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
using AppLibs.Libs;
|
||||||
|
using ManagementApp.Models;
|
||||||
|
using Microsoft.AspNetCore.Authentication;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.Graph;
|
||||||
|
using Azure.Identity;
|
||||||
|
using Microsoft.AspNetCore.Connections.Features;
|
||||||
|
using System.Diagnostics.Metrics;
|
||||||
|
using ManagementApp.Models.Services;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text.Encodings;
|
||||||
|
using System.Text;
|
||||||
|
using Microsoft.Graph.Models;
|
||||||
|
using AppLibs.Libs.Crypt;
|
||||||
|
|
||||||
|
namespace ManagementApp.Controllers
|
||||||
|
{
|
||||||
|
public class StorageController : Controller
|
||||||
|
{
|
||||||
|
Microsoft365Service service;
|
||||||
|
public StorageController(Microsoft365Service service) {
|
||||||
|
this.service = service;
|
||||||
|
}
|
||||||
|
|
||||||
|
[PageInfor("6101", "Config Storage")]
|
||||||
|
public Task<IActionResult> Index()
|
||||||
|
{
|
||||||
|
return this.ViewAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
[PageInfor("6102", "Type Storage")]
|
||||||
|
public Task<IActionResult> Type()
|
||||||
|
{
|
||||||
|
return this.ViewAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
[PageInfor("6103", "Validation Domain")]
|
||||||
|
public Task<IActionResult> ValidationDomain()
|
||||||
|
{
|
||||||
|
return this.ViewAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IActionResult> AddValidationDomain([FromForm] ValidationDomainModel model)
|
||||||
|
{
|
||||||
|
return Json(await model.AddAsync());
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IActionResult> GetValidationDomain([FromForm] ValidationDomainModel model)
|
||||||
|
{
|
||||||
|
return await model.GetValidationDomainAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IActionResult> UpdateValidationDomain([FromForm] ValidationDomainModel model)
|
||||||
|
{
|
||||||
|
return Json(await model.UpdateAsync());
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IActionResult> AddType([FromBody] TypeStorageServerModel model)
|
||||||
|
{
|
||||||
|
return Json(await model.AddAsync());
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IActionResult> GetTypeStorage([FromForm] TypeStorageServerModel model)
|
||||||
|
{
|
||||||
|
return await model.GetTypeStoragesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<IActionResult> GetTypeStorage()
|
||||||
|
{
|
||||||
|
return await TypeStorageServerModel.GetAllTypeStorage();
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<IActionResult> GetValidationDomain()
|
||||||
|
{
|
||||||
|
return await ValidationDomainModel.GetAllValidationDomain();
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IActionResult> UpdateType([FromBody] TypeStorageServerModel model)
|
||||||
|
{
|
||||||
|
return Json(await model.UpdateAsync());
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<IActionResult> GenerationAccessToken()
|
||||||
|
{
|
||||||
|
var t1 = Task<string>.Run(() =>
|
||||||
|
{
|
||||||
|
var g = Guid.NewGuid();
|
||||||
|
return Base64UrlTextEncoder.Encode(g.ToByteArray().Concat(BitConverter.GetBytes(DateTime.UtcNow.ToFileTime())).ToArray());
|
||||||
|
});
|
||||||
|
|
||||||
|
var t2 = Task<string>.Run(() => {
|
||||||
|
var g = Guid.NewGuid();
|
||||||
|
var bytes = BitConverter.GetBytes(DateTime.UtcNow.Ticks);
|
||||||
|
|
||||||
|
Array.Resize(ref bytes, 16);
|
||||||
|
|
||||||
|
|
||||||
|
byte[] data = new byte[32];
|
||||||
|
bytes.CopyTo(data, 0);
|
||||||
|
g.ToByteArray().CopyTo(data, 16);
|
||||||
|
var hash = new CRC64();
|
||||||
|
|
||||||
|
return hash.HashToString(data);
|
||||||
|
|
||||||
|
});
|
||||||
|
await Task.WhenAll(t1, t2);
|
||||||
|
|
||||||
|
return Json(new
|
||||||
|
{
|
||||||
|
idToken = t2.Result.ToLower(),
|
||||||
|
tokenValue = t1.Result
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//[HttpPost]
|
||||||
|
//public async Task<IActionResult> AddConfig
|
||||||
|
|
||||||
|
public async Task<IActionResult> LongPolling()
|
||||||
|
{
|
||||||
|
await Task.Delay(TimeSpan.FromSeconds(1));
|
||||||
|
if (this.service.Status == 0)
|
||||||
|
{
|
||||||
|
var u = await service.GetUser();
|
||||||
|
|
||||||
|
return Json(new
|
||||||
|
{
|
||||||
|
Message = service.Message,
|
||||||
|
User = (u != null)?u.Value.Select(u=>u.DisplayName).ToList<string>(): null
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return StatusCode(StatusCodes.Status204NoContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> GetSites()
|
||||||
|
{
|
||||||
|
if (this.service.Status == 0)
|
||||||
|
{
|
||||||
|
var u = await service.GetDrives();
|
||||||
|
|
||||||
|
return Json(new
|
||||||
|
{
|
||||||
|
Message = service.Message,
|
||||||
|
User = (u != null) ? u.Value.Where(a => a.IsPersonalSite == false && a.DisplayName == "Storage Backup").Select(a => new { a.Id, a.Name, a.WebUrl, a.SiteCollection, a.IsPersonalSite }): null
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return StatusCode(StatusCodes.Status204NoContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<IActionResult> LoginMicrosoft365()
|
||||||
|
{
|
||||||
|
service.Host = Request.Scheme + "://" + Request.Host.Value;
|
||||||
|
return Json(new { Path = await service.ConnectMicrosoft365() } );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
13
ManagementApp/DBModels/DBManagement.cs
Normal file
13
ManagementApp/DBModels/DBManagement.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
namespace ManagementApp.DBModels
|
||||||
|
{
|
||||||
|
public class DBManagement
|
||||||
|
{
|
||||||
|
public static string GetConnectionString()
|
||||||
|
{
|
||||||
|
string fp = Path.GetFullPath("Keys/");
|
||||||
|
//172.168.192.204
|
||||||
|
return string.Format(@"Server=103.150.124.135;Port=3306;Database=MResort;user=trungduong;password=TestDBPgq95b7r;CertificateFile={0};CertificatePassword=Pgq95b7r;charset=utf8mb4;", fp + "Certificate.pfx");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
17
ManagementApp/DBModels/TypeStorageServer.cs
Normal file
17
ManagementApp/DBModels/TypeStorageServer.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace ManagementApp.DBModels
|
||||||
|
{
|
||||||
|
public class TypeStorageServer
|
||||||
|
{
|
||||||
|
[Key]
|
||||||
|
public int IdTypeStorageServer { get; set; }
|
||||||
|
public string TypeName { get; set; }
|
||||||
|
|
||||||
|
public TypeStorageServer()
|
||||||
|
{
|
||||||
|
IdTypeStorageServer = 0;
|
||||||
|
TypeName = string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
22
ManagementApp/DBModels/ValidationDomain.cs
Normal file
22
ManagementApp/DBModels/ValidationDomain.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace ManagementApp.DBModels
|
||||||
|
{
|
||||||
|
public class ValidationDomain
|
||||||
|
{
|
||||||
|
[Key]
|
||||||
|
public int IdValidationDomain { set; get; }
|
||||||
|
|
||||||
|
public string Protocol { set; get; }
|
||||||
|
public int PortNumber { set; get; }
|
||||||
|
public string DomainName { set; get; }
|
||||||
|
|
||||||
|
public ValidationDomain()
|
||||||
|
{
|
||||||
|
IdValidationDomain = 0;
|
||||||
|
Protocol = string.Empty;
|
||||||
|
DomainName = string.Empty;
|
||||||
|
PortNumber = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
113
ManagementApp/Dapper.AExtentions/DapperCommand.cs
Normal file
113
ManagementApp/Dapper.AExtentions/DapperCommand.cs
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
using Dapper;
|
||||||
|
using System.Data.Common;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace ManagementApp.Dapper.AExtentions
|
||||||
|
{
|
||||||
|
public static class DapperCommand
|
||||||
|
{
|
||||||
|
public static async Task Insert<T>(this DbConnection connection, T obj, bool identityInsert = true)
|
||||||
|
{
|
||||||
|
var type = typeof(T);
|
||||||
|
var tableName = TableMapper.GetTableName(type);
|
||||||
|
var allProperties = PropertiesCache.TypePropertiesCache(type);
|
||||||
|
var keyProperties = PropertiesCache.KeyPropertiesCache(type);
|
||||||
|
var computedProperties = PropertiesCache.ComputedPropertiesCache(type);
|
||||||
|
var columns = PropertiesCache.GetColumnNamesCache(type);
|
||||||
|
|
||||||
|
var insertProperties = allProperties.Except(computedProperties).ToList();
|
||||||
|
var insertPropertiesString = string.Empty;
|
||||||
|
if (identityInsert)
|
||||||
|
{
|
||||||
|
insertProperties = insertProperties.Except(keyProperties).ToList();
|
||||||
|
insertPropertiesString = GetColumnsString(insertProperties, columns);
|
||||||
|
var insertedId = await connection.QueryFirstAsync<int>($@"
|
||||||
|
INSERT INTO {FormatTableName(tableName)} ({insertPropertiesString}) VALUES ({GetColumnsString(insertProperties, columns, "@")});
|
||||||
|
SELECT LAST_INSERT_ID()", obj);
|
||||||
|
keyProperties[0].SetValue(obj, insertedId);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
insertPropertiesString = GetColumnsString(insertProperties, columns);
|
||||||
|
await connection.QueryFirstAsync($@"
|
||||||
|
INSERT INTO {FormatTableName(tableName)}({insertPropertiesString})
|
||||||
|
VALUES ({GetColumnsString(insertProperties, columns, "@")})", obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task Update<T>(this DbConnection connection, T obj)
|
||||||
|
{
|
||||||
|
var type = typeof(T);
|
||||||
|
var tableName = TableMapper.GetTableName(type);
|
||||||
|
var allProperties = PropertiesCache.TypePropertiesCache(type);
|
||||||
|
var keyProperties = PropertiesCache.KeyPropertiesCache(type);
|
||||||
|
var computedProperties = PropertiesCache.ComputedPropertiesCache(type);
|
||||||
|
var columns = PropertiesCache.GetColumnNamesCache(type);
|
||||||
|
|
||||||
|
T obj1 = Activator.CreateInstance<T>();
|
||||||
|
var uProperties = allProperties.Except(computedProperties).Except(keyProperties).ToList();
|
||||||
|
var diffProperties = ComparePropertiesValue<T>(obj, obj1, uProperties);
|
||||||
|
|
||||||
|
await connection.QueryAsync($@"
|
||||||
|
UPDATE {FormatTableName(tableName)} Set {GetUpdateString(diffProperties, columns, " , ")}
|
||||||
|
WHERE {GetUpdateString(keyProperties, columns, " and ")}", obj);
|
||||||
|
}
|
||||||
|
private static List<PropertyInfo> ComparePropertiesValue<T>(T obj1, T obj2, IEnumerable<PropertyInfo> properties)
|
||||||
|
{
|
||||||
|
List<PropertyInfo> propertiesDiff = new List<PropertyInfo>();
|
||||||
|
foreach (PropertyInfo property in properties) {
|
||||||
|
if (property.GetValue(obj1, null) != property.GetValue(obj2, null))
|
||||||
|
{
|
||||||
|
propertiesDiff.Add(property);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return propertiesDiff;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private static string GetUpdateString(IEnumerable<PropertyInfo> properties, IReadOnlyDictionary<string, string> columnNames, string prefix)
|
||||||
|
{
|
||||||
|
return string.Join(prefix, properties.Select(p => $"{columnNames[p.Name]} = @{p.Name}"));
|
||||||
|
}
|
||||||
|
private static string GetColumnsString(IEnumerable<PropertyInfo> properties, IReadOnlyDictionary<string, string> columnNames, string tablePrefix = null)
|
||||||
|
{
|
||||||
|
if (tablePrefix == "target.")
|
||||||
|
{
|
||||||
|
return string.Join(", ", properties.Select(property => $"{tablePrefix}{columnNames[property.Name]} as {property.Name}"));
|
||||||
|
}
|
||||||
|
else if(tablePrefix == "@")
|
||||||
|
{
|
||||||
|
return string.Join(", ", properties.Select(property => $"{tablePrefix}{property.Name}"));
|
||||||
|
}
|
||||||
|
return string.Join(", ", properties.Select(property => $"{tablePrefix}{columnNames[property.Name]}"));
|
||||||
|
}
|
||||||
|
private static string FormatTableName(string table)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(table))
|
||||||
|
{
|
||||||
|
return table;
|
||||||
|
}
|
||||||
|
|
||||||
|
var parts = table.Split('.');
|
||||||
|
|
||||||
|
if (parts.Length == 1)
|
||||||
|
{
|
||||||
|
return $"{table}";
|
||||||
|
}
|
||||||
|
|
||||||
|
var tableName = "";
|
||||||
|
for (int i = 0; i < parts.Length; i++)
|
||||||
|
{
|
||||||
|
tableName += $"{parts[i]}";
|
||||||
|
if (i + 1 < parts.Length)
|
||||||
|
{
|
||||||
|
tableName += ".";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tableName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
111
ManagementApp/Dapper.AExtentions/PropertiesCache.cs
Normal file
111
ManagementApp/Dapper.AExtentions/PropertiesCache.cs
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace ManagementApp.Dapper.AExtentions
|
||||||
|
{
|
||||||
|
public class PropertiesCache
|
||||||
|
{
|
||||||
|
private static readonly ConcurrentDictionary<RuntimeTypeHandle, IEnumerable<PropertyInfo>> KeyProperties = new();
|
||||||
|
private static readonly ConcurrentDictionary<RuntimeTypeHandle, IEnumerable<PropertyInfo>> TypeProperties = new();
|
||||||
|
private static readonly ConcurrentDictionary<RuntimeTypeHandle, IEnumerable<PropertyInfo>> ComputedProperties = new();
|
||||||
|
private static readonly ConcurrentDictionary<RuntimeTypeHandle, IReadOnlyDictionary<string, string>> ColumnNames = new();
|
||||||
|
|
||||||
|
public static List<PropertyInfo> TypePropertiesCache(Type type)
|
||||||
|
{
|
||||||
|
if (TypeProperties.TryGetValue(type.TypeHandle, out var cachedProps))
|
||||||
|
{
|
||||||
|
return cachedProps.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
var properties = type.GetProperties().Where(ValidateProperty).ToList();
|
||||||
|
TypeProperties[type.TypeHandle] = properties;
|
||||||
|
ColumnNames[type.TypeHandle] = GetColumnNames(properties);
|
||||||
|
|
||||||
|
return properties.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static IReadOnlyDictionary<string, string> GetColumnNamesCache(Type type)
|
||||||
|
{
|
||||||
|
if (ColumnNames.TryGetValue(type.TypeHandle, out var cachedProps))
|
||||||
|
{
|
||||||
|
return cachedProps;
|
||||||
|
}
|
||||||
|
|
||||||
|
var properties = type.GetProperties().Where(ValidateProperty).ToList();
|
||||||
|
TypeProperties[type.TypeHandle] = properties;
|
||||||
|
ColumnNames[type.TypeHandle] = GetColumnNames(properties);
|
||||||
|
|
||||||
|
return ColumnNames[type.TypeHandle];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool ValidateProperty(PropertyInfo prop)
|
||||||
|
{
|
||||||
|
var result = prop.CanWrite;
|
||||||
|
result = result && (prop.GetSetMethod(true)?.IsPublic ?? false);
|
||||||
|
result = result && (!prop.PropertyType.IsClass || prop.PropertyType == typeof(string) || prop.PropertyType == typeof(byte[]));
|
||||||
|
result = result && prop.GetCustomAttributes(true).All(a => a.GetType().Name != "NotMappedAttribute");
|
||||||
|
|
||||||
|
var writeAttribute = prop.GetCustomAttributes(true).FirstOrDefault(x => x.GetType().Name == "WriteAttribute");
|
||||||
|
if (writeAttribute != null)
|
||||||
|
{
|
||||||
|
var writeProperty = writeAttribute.GetType().GetProperty("Write");
|
||||||
|
if (writeProperty != null && writeProperty.PropertyType == typeof(bool))
|
||||||
|
{
|
||||||
|
result = result && (bool)writeProperty.GetValue(writeAttribute);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<PropertyInfo> KeyPropertiesCache(Type type)
|
||||||
|
{
|
||||||
|
if (KeyProperties.TryGetValue(type.TypeHandle, out var cachedProps))
|
||||||
|
{
|
||||||
|
return cachedProps.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
var allProperties = TypePropertiesCache(type);
|
||||||
|
var keyProperties = allProperties.Where(p => p.GetCustomAttributes(true).Any(a => a.GetType().Name == "KeyAttribute")).ToList();
|
||||||
|
|
||||||
|
if (keyProperties.Count == 0)
|
||||||
|
{
|
||||||
|
var idProp = allProperties.Find(p => string.Equals(p.Name, "id", StringComparison.CurrentCultureIgnoreCase));
|
||||||
|
if (idProp != null)
|
||||||
|
{
|
||||||
|
keyProperties.Add(idProp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyProperties[type.TypeHandle] = keyProperties;
|
||||||
|
return keyProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<PropertyInfo> ComputedPropertiesCache(Type type)
|
||||||
|
{
|
||||||
|
if (ComputedProperties.TryGetValue(type.TypeHandle, out var cachedProps))
|
||||||
|
{
|
||||||
|
return cachedProps.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
var computedProperties = TypePropertiesCache(type).Where(p => p.GetCustomAttributes(true).Any(a => a.GetType().Name == "ComputedAttribute")).ToList();
|
||||||
|
ComputedProperties[type.TypeHandle] = computedProperties;
|
||||||
|
return computedProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IReadOnlyDictionary<string, string> GetColumnNames(IEnumerable<PropertyInfo> props)
|
||||||
|
{
|
||||||
|
var ret = new Dictionary<string, string>();
|
||||||
|
foreach (var prop in props)
|
||||||
|
{
|
||||||
|
var columnAttr = prop.GetCustomAttributes(false).SingleOrDefault(attr => attr.GetType().Name == "ColumnAttribute") as dynamic;
|
||||||
|
// if the column attribute exists, and specifies a column name, use that, otherwise fall back to the property name as the column name
|
||||||
|
ret.Add(prop.Name, columnAttr != null ? (string)columnAttr.Name ?? prop.Name : prop.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
57
ManagementApp/Dapper.AExtentions/TableMapper.cs
Normal file
57
ManagementApp/Dapper.AExtentions/TableMapper.cs
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Data;
|
||||||
|
|
||||||
|
namespace ManagementApp.Dapper.AExtentions
|
||||||
|
{
|
||||||
|
public class TableMapper
|
||||||
|
{
|
||||||
|
private static readonly ConcurrentDictionary<RuntimeTypeHandle, string> TableNames = new();
|
||||||
|
|
||||||
|
private static string _prefix = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Used to setup custom table conventions.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tablePrefix">table name prefix</param>
|
||||||
|
/// <param name="tableSuffix">table name suffix</param>
|
||||||
|
// ReSharper disable once UnusedMember.Global
|
||||||
|
public static void SetupConvention(string tablePrefix)
|
||||||
|
{
|
||||||
|
if (!TableNames.IsEmpty)
|
||||||
|
{
|
||||||
|
throw new InvalidConstraintException("TableMapper.SetupConvention called after usage.");
|
||||||
|
}
|
||||||
|
|
||||||
|
_prefix = tablePrefix;
|
||||||
|
|
||||||
|
TableNames.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string GetTableName(Type type)
|
||||||
|
{
|
||||||
|
if (TableNames.TryGetValue(type.TypeHandle, out var name))
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
var tableAttr = type.GetCustomAttributes(false).SingleOrDefault(attr => attr.GetType().Name == "TableAttribute") as dynamic;
|
||||||
|
if (tableAttr != null)
|
||||||
|
{
|
||||||
|
name = tableAttr.Name;
|
||||||
|
|
||||||
|
if (tableAttr.Schema != null)
|
||||||
|
{
|
||||||
|
name = tableAttr.Schema + "." + tableAttr.Name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
name = type.IsInterface && type.Name.StartsWith("I") ? type.Name.Substring(1) : type.Name;
|
||||||
|
name = $"{_prefix}{name}";
|
||||||
|
}
|
||||||
|
|
||||||
|
TableNames[type.TypeHandle] = name;
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
155
ManagementApp/Json/navlist.json
Normal file
155
ManagementApp/Json/navlist.json
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "1000",
|
||||||
|
"name": "Dashboard",
|
||||||
|
"icon": "home",
|
||||||
|
"group": 0,
|
||||||
|
"url": "/",
|
||||||
|
"sub-item": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "6000",
|
||||||
|
"name": "Storage Management",
|
||||||
|
"icon": "",
|
||||||
|
"group": 1,
|
||||||
|
"url": "",
|
||||||
|
"sub-item": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "6100",
|
||||||
|
"name": "Storage Setting",
|
||||||
|
"icon": "storage",
|
||||||
|
"group": 0,
|
||||||
|
"url": "",
|
||||||
|
"sub-item": [
|
||||||
|
{
|
||||||
|
"id": "6101",
|
||||||
|
"name": "Config Storage",
|
||||||
|
"url": "/Storage"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "6104",
|
||||||
|
"name": "Storage Server",
|
||||||
|
"url": "/Storage/StorageServer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "6102",
|
||||||
|
"name": "Type Storage",
|
||||||
|
"url": "/Storage/Type"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "6103",
|
||||||
|
"name": "Validation Domain",
|
||||||
|
"url": "/Storage/ValidationDomain"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8000",
|
||||||
|
"name": "Rooms Management",
|
||||||
|
"icon": "",
|
||||||
|
"group": 1,
|
||||||
|
"url": "",
|
||||||
|
"sub-item": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8100",
|
||||||
|
"name": "Rooms",
|
||||||
|
"icon": "storage",
|
||||||
|
"group": 0,
|
||||||
|
"url": "",
|
||||||
|
"sub-item": [
|
||||||
|
{
|
||||||
|
"id": "8101",
|
||||||
|
"name": "Add Room",
|
||||||
|
"url": "/Rooms/Add"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8102",
|
||||||
|
"name": "Rooms List",
|
||||||
|
"url": "/Rooms"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8103",
|
||||||
|
"name": "Room Type",
|
||||||
|
"url": "/Rooms/RoomType"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8200",
|
||||||
|
"name": "Room Price",
|
||||||
|
"icon": "storage",
|
||||||
|
"group": 0,
|
||||||
|
"url": "/CMS/ListPage",
|
||||||
|
"sub-item": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "2",
|
||||||
|
"name": "QUẢN LÝ SẢN PHẨM",
|
||||||
|
"icon": "",
|
||||||
|
"group": 1,
|
||||||
|
"url": "",
|
||||||
|
"sub-item": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "3",
|
||||||
|
"name": "Danh Mục Sản Phẩm",
|
||||||
|
"icon": "catalogue",
|
||||||
|
"group": 0,
|
||||||
|
"url": "",
|
||||||
|
"sub-item": [
|
||||||
|
{
|
||||||
|
"id": "3-1",
|
||||||
|
"name": "Thương Hiệu",
|
||||||
|
"url": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "3-2",
|
||||||
|
"name": "Nhà Phân Phối",
|
||||||
|
"url": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "3-3",
|
||||||
|
"name": "Nhà Sản Xuất",
|
||||||
|
"url": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "4",
|
||||||
|
"name": "Nhóm Sản Phẩm",
|
||||||
|
"icon": "product",
|
||||||
|
"group": 0,
|
||||||
|
"url": "",
|
||||||
|
"sub-item": [
|
||||||
|
{
|
||||||
|
"id": "4-1",
|
||||||
|
"name": "Xem Sản Phẩm",
|
||||||
|
"url": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "4-2",
|
||||||
|
"name": "Thêm Sản Phẩm",
|
||||||
|
"url": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "13",
|
||||||
|
"name": "Tạo Website",
|
||||||
|
"icon": "storage",
|
||||||
|
"group": 0,
|
||||||
|
"url": "/CMS/CreateWS",
|
||||||
|
"sub-item": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "14",
|
||||||
|
"name": "Thêm Trang",
|
||||||
|
"icon": "storage",
|
||||||
|
"group": 0,
|
||||||
|
"url": "/CMS/AddPageSite",
|
||||||
|
"sub-item": ""
|
||||||
|
}
|
||||||
|
|
||||||
|
]
|
22
ManagementApp/Keys/ca-cert.pem
Normal file
22
ManagementApp/Keys/ca-cert.pem
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDozCCAougAwIBAgIUL6RvqTtdU0Q0W+rJ8++XRi2mgSAwDQYJKoZIhvcNAQEL
|
||||||
|
BQAwYDELMAkGA1UEBhMCVk4xDDAKBgNVBAgMA0hDTTEMMAoGA1UEBwwDSENNMREw
|
||||||
|
DwYDVQQKDAhBVEcgQ29ycDEMMAoGA1UECwwDQVRHMRQwEgYDVQQDDAtNYXJpYURC
|
||||||
|
IEFURzAgFw0yMzEyMDkwNDE0MTZaGA8zMDIzMDQxMTA0MTQxNlowYDELMAkGA1UE
|
||||||
|
BhMCVk4xDDAKBgNVBAgMA0hDTTEMMAoGA1UEBwwDSENNMREwDwYDVQQKDAhBVEcg
|
||||||
|
Q29ycDEMMAoGA1UECwwDQVRHMRQwEgYDVQQDDAtNYXJpYURCIEFURzCCASIwDQYJ
|
||||||
|
KoZIhvcNAQEBBQADggEPADCCAQoCggEBALTd7nfKimOSLzDkKpAG3/2/O6hiHfbA
|
||||||
|
tJSPJHfALd7GzSYs3cTAz0ddyDvjxyX/Dpxli1E4j2roQ09wJ/o91Sbdh390kbT8
|
||||||
|
oYV1dJgx+V85LC3KrcjNsNLIfnwehfnzBcKp4JltCbuxqIh0oztINJa1Ymw1uypz
|
||||||
|
TEOmHkW/XwdZHgSlE75U4Mq60UF3TcyoCgwz2gKBM8RLR1hWqWaw83gZ0Kk1XiAL
|
||||||
|
oX2iW7lAscSfC6I9FKA1FzM5uwxkHJIvs1kFIPb3s9EIBXNaGq4hPwUCxYc+++7V
|
||||||
|
+Zztny/8sUHmVJRlVONDmYN+U/2UZ2dmp61XxM0dfUqgEdQvxYSekOUCAwEAAaNT
|
||||||
|
MFEwHQYDVR0OBBYEFPDDdKr/JJomAVOZ7NKxU0ckd/yAMB8GA1UdIwQYMBaAFPDD
|
||||||
|
dKr/JJomAVOZ7NKxU0ckd/yAMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL
|
||||||
|
BQADggEBALAyl/FmcustRD7LCUfl1SjNC8KSTh7LXaUQW5ijIW0733tkONvTriiN
|
||||||
|
DEWE6CWbYCSe/3/5da7QW/C0tMy/mfhV2waDW2JbfIIKdBIiemTIgcMII3B9+G17
|
||||||
|
loVjWWD3jSmxYzdwKsxP4QsUtVHcMyG7Xdp6OIABfI3cIbBqmMxmjiADCdEf+3OS
|
||||||
|
anqSDH/2LxGWPOPP3MRgxNRszz4BEUp5O24YR+uOZ8WXm8Me5STqzu5pPy192Xoz
|
||||||
|
HmCOvjqcAXX56TI19A+HLjkKsOB8rc2yOUtJFG6CTzxfE1rwugcKwDHKncxRApf3
|
||||||
|
967O+/I0DlUh4irbGrqW0pBM/1AStxA=
|
||||||
|
-----END CERTIFICATE-----
|
20
ManagementApp/Keys/client-cert.pem
Normal file
20
ManagementApp/Keys/client-cert.pem
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDOTCCAiECAQEwDQYJKoZIhvcNAQELBQAwYDELMAkGA1UEBhMCVk4xDDAKBgNV
|
||||||
|
BAgMA0hDTTEMMAoGA1UEBwwDSENNMREwDwYDVQQKDAhBVEcgQ29ycDEMMAoGA1UE
|
||||||
|
CwwDQVRHMRQwEgYDVQQDDAtNYXJpYURCIEFURzAgFw0yMzEyMDkwNDE2NTJaGA8z
|
||||||
|
MDIzMDQxMTA0MTY1MlowYzELMAkGA1UEBhMCVk4xDDAKBgNVBAgMA0hDTTEMMAoG
|
||||||
|
A1UEBwwDSENNMREwDwYDVQQKDAhBVEcgQ29ycDEMMAoGA1UECwwDQVRHMRcwFQYD
|
||||||
|
VQQDDA5NYXJpYURCIENsaWVudDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
|
||||||
|
ggEBANDsm2xLqy+xli31OUsNdYEk+6ftBZWRAFUhpt1ARRZJ4Ks3Z0k6AbJEgIIk
|
||||||
|
UtmdfbujOoG5FZYofke4RaX+4MnlX+8llWFE22qXhY77LTNxinOo5STu5YybjGAL
|
||||||
|
VlDoEwG1B+aVBovK20t4q6hSabuWEbatKi9mrxmOm6T5j+Xa/9OpJnGB/cSCaE9t
|
||||||
|
kD3LpB2dJ284o28/Ec2J/8/C4Hby0Pg17BqXMMfGELF04FiP23sSsijciSEsJaMD
|
||||||
|
tqkyfAAbUUR0C1xqCAZujqZEzsd2IAgxAeymF2CFo2VzRq1r9wJN8hUUr6bxVReM
|
||||||
|
KUvJYBh6Ai8nsqt7cT18yrLMdD8CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAMAjc
|
||||||
|
cfZwA4KDy42G7aVNqJ0jSVm9sklGAARC6WoThx1uT0t+p0KYmPRWuw19tEvKYQcB
|
||||||
|
vMCv4Tkt41nRy9RkvXa9Q9PhxQxbfZNN9eakFHT/8sLhqUZPLuUPbUHOdDyue5z3
|
||||||
|
Y2xj4QKO10e1UDU3OeFBT6FTUeHLm4+aminaztndJ3XhLrx3ukPkdr7qlU9tB3t4
|
||||||
|
iXVTc6DkcRZrucK2uwpiIWBFV/sedqlHhP5gAxPgI7wHcicwR87sPKFeM29MTQcr
|
||||||
|
jIG007zxvSWPZ11dl/s2ITzoMxaPd+7uMnstgVfha1TbxQxI2CSYT/luxyoXgh0l
|
||||||
|
X3lfLzs19rkIxuqIdA==
|
||||||
|
-----END CERTIFICATE-----
|
27
ManagementApp/Keys/client-key.pem
Normal file
27
ManagementApp/Keys/client-key.pem
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEowIBAAKCAQEA0OybbEurL7GWLfU5Sw11gST7p+0FlZEAVSGm3UBFFkngqzdn
|
||||||
|
SToBskSAgiRS2Z19u6M6gbkVlih+R7hFpf7gyeVf7yWVYUTbapeFjvstM3GKc6jl
|
||||||
|
JO7ljJuMYAtWUOgTAbUH5pUGi8rbS3irqFJpu5YRtq0qL2avGY6bpPmP5dr/06km
|
||||||
|
cYH9xIJoT22QPcukHZ0nbzijbz8RzYn/z8LgdvLQ+DXsGpcwx8YQsXTgWI/bexKy
|
||||||
|
KNyJISwlowO2qTJ8ABtRRHQLXGoIBm6OpkTOx3YgCDEB7KYXYIWjZXNGrWv3Ak3y
|
||||||
|
FRSvpvFVF4wpS8lgGHoCLyeyq3txPXzKssx0PwIDAQABAoIBAEeAQmzctLh84XXX
|
||||||
|
EAWUlJtfKdU9tASM/H0mKDJeVYacQAy4yFtyQ7Rb51Mi1Uvur2IxKcvNqQqbzyQC
|
||||||
|
d6uowAu4uY1h4m7InwMq2iWl5sFNYWHV8p4iOGNXtMIF/0NvOVoDN7H9XKEpCsYY
|
||||||
|
hT70/YSahnNrbh2M2e44NSJP2qSCIRguxtrRU1zDXKbqikGbgEi9n9hJkQ2nn/uz
|
||||||
|
kqfiJZx4H0MZRS3z1KR5rLkJSFsV+OrwYKQ7/PulkXlXEwUH5lOb1E4THAYjIMmh
|
||||||
|
8+ZLATpL33FrOAT4f29Zkrq4RPbLDJPh2TKk+5qxg9oF6lfMtOtvgTBpEXN9TPmk
|
||||||
|
aoxK1eECgYEA9yQIrCB8Pv/sGUVQPKHM4BBjM9hFM6QxVx0UizCMWjPCsvVSf06J
|
||||||
|
WzKZvj2i1w0bdxr5j/rSXEabtyLaxUbkxfG5270oKp1ksNl6gLXBzy6hHFMx68Dr
|
||||||
|
85HnaAVhWj4pMAGCQmDudmjbSsjbM+ttc5C0BKSiaePtD0aBin/REg8CgYEA2Gne
|
||||||
|
AlbdPzqqfrkhqXB9EnYwTNi2Zzr1SPhNY5lHslL3AXOSGTkFe+mWAAll7ole6Uo/
|
||||||
|
sbCeJw9KJOTkTsJRO+N2ipaKXghXYj0BDHbdVSmsB9AKIVHmfT9RW+97/t3/UU4K
|
||||||
|
Er865CIwfcB0h5oOJGNKQfqrbkdkvWa9qOa16tECgYEAhOPzZdrx9E5Y/h2vT2sR
|
||||||
|
Z0pojXA1hdc8UMNqUI4Cal56yw/vFFV+tnM3CHzMGycJJbpzh2AvzT6KbKdpS7sb
|
||||||
|
OPUKI4ZLGt8XTaEjpiIV3PoN19VEeqh6N7a039JEzumt7ApjqJ3GnBU2Fbh7Ziep
|
||||||
|
6wJcSkLcsmPFDPm0nmysVzECgYAbPwDndH44Zq9ucuptBa+Jcn3UPvh/+KlG/ZPo
|
||||||
|
tTSUm+NjOGStbkNlfVwYNxaxOHRNlL5+JYlTy5X/HR4tWEOX8aRMAHX9LrmpsZp/
|
||||||
|
Mjvda/ivpx6PYVtOa3lXxMfsp5BscRHNmGvWqwNF4cQKCng7VpDTy7ZnlO929Qdt
|
||||||
|
y1Yd8QKBgDBrqVavzOzHd1pNj9Q52C27O0iwo6FcPpOidGuJYxELGfQFs9ubpCqS
|
||||||
|
kBfVuY6+uJJuQbSa1eAvhWf070FMwvR7IORd0LHZLStDHW1znPEKWz8Fp+1+RqPU
|
||||||
|
EFhYsmAs/+vIQiFyAauofFFaypzJMkQfgNr5m0QWn7OdHWtv5QoT
|
||||||
|
-----END RSA PRIVATE KEY-----
|
31
ManagementApp/Keys/tmp/ca-cert.pem
Normal file
31
ManagementApp/Keys/tmp/ca-cert.pem
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIFXzCCA0egAwIBAgIUTZ+8jep6d8AHse8UHxtNbeIVtfkwDQYJKoZIhvcNAQEL
|
||||||
|
BQAwPjELMAkGA1UEBhMCVk4xDDAKBgNVBAgMA0hDTTEhMB8GA1UECgwYSW50ZXJu
|
||||||
|
ZXQgV2lkZ2l0cyBQdHkgTHRkMCAXDTI0MDYyNzEwNTExN1oYDzMwMjMxMDI5MTA1
|
||||||
|
MTE3WjA+MQswCQYDVQQGEwJWTjEMMAoGA1UECAwDSENNMSEwHwYDVQQKDBhJbnRl
|
||||||
|
cm5ldCBXaWRnaXRzIFB0eSBMdGQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
|
||||||
|
AoICAQCcFsxz7+LrIQAcjFGcABlPeg+SAjfA4EdXmQlaTsO/KPXOMMvvXUcTFc8J
|
||||||
|
rYs/OVJ2U3XE0TQzgrU+/wcm53H6NRE7mNPzetQQL2go3Ry1Waw8Q0/Msw/MopCJ
|
||||||
|
laUOPMUBf6yJB5HcCvdQrk7dWkiJ9r6PNjwKeC5qsM72kqQj9FmSYWhog715PPGB
|
||||||
|
1Kp1hDFfVOkLBJg+v90XqsuebCqMTt5fdFRjY0a2SM+tih0LQhEvku1wzfEBWSVT
|
||||||
|
boUY+SD3d4Z8ZFH+Rth9zQIwtuGfzl59DWZb+PgoHA7X7nd3nG9o4fhM8e0PmWpI
|
||||||
|
kBcEH9IeaOCP4qRO6VtnL9wqiJOraHx6gkLdj+AaEXuxln+Wb89cdR+QLbz1JHF8
|
||||||
|
G1DgAkku+R7zxL+QjfD0/BAYZtNKdC83E2BnuiPNNZaPRa6CymY9cRf0vK/UHGUc
|
||||||
|
enPXpfGjcxoc9jnqWqkGjAU9WsEqV4hj8e4uUkHpN0UQOMTfIIjdewtLakJ3qDXD
|
||||||
|
NM1HE/uIHVR3vv7gVot4jtrIDmjRhj6SJe50sPx8gmlbMafoeHzZczN54pkBFraE
|
||||||
|
uVALCdm5OchTdM/4EgCejUQZt5JGekphQOyPPhHscRoAp6tn1qk3BojS3/6sXAzl
|
||||||
|
8pRKX32JOuQcQqjSTRorC7TsskWfIDNnds+WETRtM4GJqCRGIwIDAQABo1MwUTAd
|
||||||
|
BgNVHQ4EFgQUAU9JN0sE9+a8tPunsQjhNHADZDwwHwYDVR0jBBgwFoAUAU9JN0sE
|
||||||
|
9+a8tPunsQjhNHADZDwwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC
|
||||||
|
AgEAPNY0r2AM7LPQhdAYFaejo87p/K58D1f4r2jq43/CwPJbI9OgzBmVuXrW9mf3
|
||||||
|
mPjfd24bWGhUAWFkJgg9/BL/fLDYA0u6WQfG5p/nmfQJ1ZnXlKDyW1dYOffAVWN8
|
||||||
|
GkKV9nxWgJv4E3bqP7gX4tc1MIq+MYMLuECDnGCnUaSZYVajMrDS/gwv9FoVNqYV
|
||||||
|
r/x0fMvMRTThSOQBLcnk3/AzZOfKOTmSMaoFfSPpITf1HAB6s5uOCvtBXLriAu1P
|
||||||
|
cOBWP5lX5HAooqSxC+B1tNQ88j4QJkKpRKARjWEYBMSexcDJfxpwsKS10B4ZdG4q
|
||||||
|
T7q3K79LUbs1DlCxPkSZ57LRZ4tyf7Rfcn3a8syRvTUQaUSX9B3Ktbc62F1wRkAi
|
||||||
|
iasdv284jCd+6UkBmp78KwbuWJ11m/J7cb3ZJ9WHR94oqYiDmh/8DXvRc+tS6TPv
|
||||||
|
nSC8JBsRez88E9pOAmLOjzd5Rgprwh3TdfzQh4TTEyUMjK05CZPJ0vGID7jCHvet
|
||||||
|
cVHGQ84WM6cuP1B0J+a60/QtXO1DN/LXt/vcRhmy4ie4FRMjY8+p7wui7G/1SeXz
|
||||||
|
s2cLuARLtpKhJAy7Jkw+Yc3Un21Qsw7Nj1pxDVICv1ifa5GXs/xJGTQsUS9v+Xak
|
||||||
|
f2nFsUeCFtmpfrKbcjVPdEBo5vQYmFdBcdjr5dL31/q4OUE=
|
||||||
|
-----END CERTIFICATE-----
|
52
ManagementApp/Keys/tmp/ca-key.pem
Normal file
52
ManagementApp/Keys/tmp/ca-key.pem
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQCcFsxz7+LrIQAc
|
||||||
|
jFGcABlPeg+SAjfA4EdXmQlaTsO/KPXOMMvvXUcTFc8JrYs/OVJ2U3XE0TQzgrU+
|
||||||
|
/wcm53H6NRE7mNPzetQQL2go3Ry1Waw8Q0/Msw/MopCJlaUOPMUBf6yJB5HcCvdQ
|
||||||
|
rk7dWkiJ9r6PNjwKeC5qsM72kqQj9FmSYWhog715PPGB1Kp1hDFfVOkLBJg+v90X
|
||||||
|
qsuebCqMTt5fdFRjY0a2SM+tih0LQhEvku1wzfEBWSVTboUY+SD3d4Z8ZFH+Rth9
|
||||||
|
zQIwtuGfzl59DWZb+PgoHA7X7nd3nG9o4fhM8e0PmWpIkBcEH9IeaOCP4qRO6Vtn
|
||||||
|
L9wqiJOraHx6gkLdj+AaEXuxln+Wb89cdR+QLbz1JHF8G1DgAkku+R7zxL+QjfD0
|
||||||
|
/BAYZtNKdC83E2BnuiPNNZaPRa6CymY9cRf0vK/UHGUcenPXpfGjcxoc9jnqWqkG
|
||||||
|
jAU9WsEqV4hj8e4uUkHpN0UQOMTfIIjdewtLakJ3qDXDNM1HE/uIHVR3vv7gVot4
|
||||||
|
jtrIDmjRhj6SJe50sPx8gmlbMafoeHzZczN54pkBFraEuVALCdm5OchTdM/4EgCe
|
||||||
|
jUQZt5JGekphQOyPPhHscRoAp6tn1qk3BojS3/6sXAzl8pRKX32JOuQcQqjSTRor
|
||||||
|
C7TsskWfIDNnds+WETRtM4GJqCRGIwIDAQABAoICAA/9AdpKUysUiUdjVCSvmegb
|
||||||
|
L6ccFQvrrUMayOt4L/LPxkXll64gFtysmjV6kk3amEjIicKsTzWLiPc39kqU4Ibp
|
||||||
|
kqdRIzzIcxppULkG1R76XXsaxfzIxrCGYlnFe0+3B9L8efbbUKSCdwzLngZsbgu7
|
||||||
|
u4891e6YmuCQ1dJJ+Qg5ykcFNUWnYOwfQvmyh/dboBcMwoY/ZTzgOExpUUwb9kvC
|
||||||
|
9GJArzgy/hZD5Qn4oLr7fHksCqhIYAxsTjd6laWWNztCAgOR3xg1t41DR5sn0Hqn
|
||||||
|
D+StT7PSD9FD9n1FzvTwkDTlGKMBEPBNHabrI4BnpgU5Zu82HvB6VMOAEoRE0yNN
|
||||||
|
lychmsboqJbulaVRV7HJL/u7WQ3Ng12wQAbjJ1j7M5f4l3UbXoHk3fXg01Fz3kVC
|
||||||
|
C+2aTebcgK/l3oAjvuNDXeliLtBQLVt8cPt9CR8sCpTkUbSuTYDuH3k9JUiqOM5W
|
||||||
|
l7OJtM167tzop2rEpkPdjuDi0M1ilNKu4VwqZeq1exvI+/4cmgNwuO6fLtZz8DqR
|
||||||
|
7FKkzdc8RE150/0tC5YcJWOBTF7GAfwFc58VNyABY9b2h6vT64ulSTVabhRzFnWL
|
||||||
|
KdCzKzeDO1qbd3L64QZ4nWJ3/bMJFInYCjR4A5iAx4aZv4RtxR6O9tlozg9yXzEj
|
||||||
|
4GFJz9ycCriMEAbxaOppAoIBAQDWIAtpTDLXa4eebE66phigQ1VcTxgEx68MMVaj
|
||||||
|
YFFwY20PKnet/ZrHOAAkIuyJe8ZB+F9W2rXvE/qByZ1ealdMs1e+CJH7JLoN5GOA
|
||||||
|
QKcUW41vrz9Vh/Wk+9eITdgLqSDJ0muqPaKvv6vf8XwEkeQC7WTaZ6IzDVNVWXGO
|
||||||
|
6tu62T5l1j6q2gX4reSPXjno9VMDaxdBo3+DLcXvA1Pts58SqNiy6ZsJYkVAINSE
|
||||||
|
1BGBm94UBJynvtlRnZCPfLr8gIrFfUbtG6VliE1fOpIB7ma5uyAr5pASZgYLfQt6
|
||||||
|
pJlZt6zKdzeVN/qUCVxAoR8URq/oqshFtfzAxxq0WufCKbAvAoIBAQC6nTxjI7kK
|
||||||
|
7BpHkHBIYZcZRUpauD94RbsbgL3jFweqZXcCf2I9cPOM1tNoQoG8yQBQOCcWHsMN
|
||||||
|
jFtH00ZmrJVEhyC6kK64oeGWIYpWbNeEcGlECI3F1ODujveK7EvQxd+NQG7Terrb
|
||||||
|
IEbkrivm+X3s4W6ST/w4iMzG8RnKHAmET0bt641fV2FWHCT7lEoB9ark85FsuKHj
|
||||||
|
WPZVGz7daxv9PjjcDjmE3lX2jjGG4tD5n24RQwh2rUyiYVoy4l/KyMuL8eiGFMSI
|
||||||
|
Ygsc7gVYIim9j1vdLrYEaZgRfB5DnNe3GXA9ZXNAz7+BB6QiKOHZsNpHObbdxPYZ
|
||||||
|
pxMCnky58DhNAoIBAD7xgok8hgF/MYmnaulBJCIQSQpuka/uBw39futdx/LSt19q
|
||||||
|
621xDEudsaTtwzyS7u+7lEMS3cJezBfU7XawqeL5IUTSfh8mZ67nwTwVRUgdtZDs
|
||||||
|
IiEBa3tJMM13nJeo6uOJAG812RnyrRKSiRNK04zsveXZ6vs44pNHTLNnZJojfE0x
|
||||||
|
UpCksHaun25pk3pgizuJAnggGL61+OZOwyAv2gYBLlpBg3qZsaOtQuuc71x7NigK
|
||||||
|
RwakenucZr9XOhw5qRFuxyeyJceX7q6cqAj7TKUyVb2x9A4Egahk5LfzpMST0q5d
|
||||||
|
pzAtGXLk4YJ6Gom6UcGCWobrfVYp8TatNk2ENa8CggEBAIV41Kor8LupJxqsakK6
|
||||||
|
2jGO56F/SpYhebQwHqB/5lGvhLFans9HLEs9k7NsbhKyyPCXWQ1vLx9PljIHIMFr
|
||||||
|
CtAavgPyW6Ve01Rn5OPvsS3eoMuyOoSWv9KgmtjYLVnDTSNgRGQp0d/MdCg3ktr+
|
||||||
|
81wr2MP5RXLCFYTtCP8Pkpb5hMfCxDi+7LWEJ8dwxoYkSfi7ZPYYEGHlTTqN5CbF
|
||||||
|
5xz4Ff7+hZFM3Lsd9Lp/G+yOZVEfWrxXMwqpCrR+SPlnKH6NpTvROsg5J62naFcj
|
||||||
|
CCu2j4PhVvpM9CD9X0AIvBkPrsGbABYJAPWum2x7RR5IabarxulTaJnsb6Jdyo7r
|
||||||
|
C7kCggEBALBEyLMJk4lxfYe+VTBxVuFxpp5VsTd4X50dotfFbpcmu3D/hwXEXvLD
|
||||||
|
+WnSwoi/tjKNkurmHYlL6VvcVr2rEt9nWjtRLtJ5Sd07h1o996fo7sIPPPumHyE0
|
||||||
|
ru5iXMgDdTfamGz04OR4FFRvOBtjzPnx838/Ce/R8Fvt3TSEvOJvP9vkHdLmkyTI
|
||||||
|
u9hNf8/Y02NIckpKrOLUrs8AgimCtU//G+5+X+8HhpBYGidTlJt1uqMXWttr9pP1
|
||||||
|
vn/cd7YAEx52T+pF1JmtbVPCcCpcQRNVgZedqdgweEpueXj8/z5aQwEwEMR86hh9
|
||||||
|
LE0sbAXTnYHPn5VpqsNvA7MKGE/CSQA=
|
||||||
|
-----END PRIVATE KEY-----
|
24
ManagementApp/Keys/tmp/server-cert.pem
Normal file
24
ManagementApp/Keys/tmp/server-cert.pem
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIID+TCCAeECAQEwDQYJKoZIhvcNAQELBQAwPjELMAkGA1UEBhMCVk4xDDAKBgNV
|
||||||
|
BAgMA0hDTTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMCAXDTI0
|
||||||
|
MDYyNzEwNTIyNFoYDzMwMjMxMDI5MTA1MjI0WjBFMQswCQYDVQQGEwJBVTETMBEG
|
||||||
|
A1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkg
|
||||||
|
THRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6BK6MywEI1a0ywl7
|
||||||
|
/W3Skm5G/tmbN3S38wSjoedZNY/VtdwnVngmx5MrJ8HjoEx6poFTBrwdvPlCLzZ6
|
||||||
|
ZIS/J9rAUyBLwLQWUUa8qJG8HODOrIhoD0V/B6GXJ6m/e1ptA/FkEbX0+0yWQK+8
|
||||||
|
ki603cYHo4faByjmkeOmGfi8W9JrUuVLJhUrNAvr7y7c84BPlXjcdIoWIgI9fNbO
|
||||||
|
HKm2yPu9/76f9N5OKHY7s7RatYTM0HSNBP57Q9uBhnYp0Rp4ZWX2+zqcCM6cwpEe
|
||||||
|
UIvl7E5/StHhQaaX3MpHFvGA7cRV42R+M2vfXIUW2WPzd/9hIpTIAj0oDQTiH14h
|
||||||
|
mkK/ywIDAQABMA0GCSqGSIb3DQEBCwUAA4ICAQCEV79KlCLYzMcfYUEEJXtVaiT+
|
||||||
|
MaAx4czH4QiEvqKyDRxzQys9wjtO4n5vVMtUhXmX6+87u00HaI8K+80Hb0kFghLH
|
||||||
|
iQWAE3tcCr3y/ILLjm9f33dxBz6G+tYw3twRhe/vhtyExnfdZSzx2Kji+mWjZAdP
|
||||||
|
no1lRnxoCIMyUkCkgcfDwOwbyfsqiuyHEeN+pJZ44gTDNja6Tesm4tTey4Ljr8Yi
|
||||||
|
mTXsjR3+c9SIke3C+VuF0B7313BK5r1der/nP4UFmSuq4iNNsCHUUJJfGLa985Gc
|
||||||
|
qWPPEhr+4b29wYAEtp2tHU1fAJU9U2ZwviFUd+QQu+gYaKze+aMB4HmZoLjDJafz
|
||||||
|
Ng+tA5wPuVNmihbgih2kqo8oQy4loGlHj9UQVZ6cAqvX+wfxApd2M+hYDjIczwJ8
|
||||||
|
ExInunim50byFJ+gXn+Hyy1v0GURdyy45vlcZWdVbjupQlcDkpewSU+L9387Uq82
|
||||||
|
WQFpiu5G73i2VF4HRF8f8gjMwKF4BIABosNzCVk31IGtt2Cpb0F9vnOgosJsFAuS
|
||||||
|
SwqDd/e505GS3/2C9PAraysfsig9njLISCPkZPzof/0GxagC9p4WHcB8MbfVnJXz
|
||||||
|
6YX4tTH6KuSjLqiuDHZOZC9LtLJZej6lToggK3PcdH8pVJvdbTIzt/8BF+8Um7v/
|
||||||
|
1JzsKt36uHOGpbCOew==
|
||||||
|
-----END CERTIFICATE-----
|
28
ManagementApp/Keys/tmp/server-key.pem
Normal file
28
ManagementApp/Keys/tmp/server-key.pem
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDoErozLAQjVrTL
|
||||||
|
CXv9bdKSbkb+2Zs3dLfzBKOh51k1j9W13CdWeCbHkysnweOgTHqmgVMGvB28+UIv
|
||||||
|
NnpkhL8n2sBTIEvAtBZRRryokbwc4M6siGgPRX8HoZcnqb97Wm0D8WQRtfT7TJZA
|
||||||
|
r7ySLrTdxgejh9oHKOaR46YZ+Lxb0mtS5UsmFSs0C+vvLtzzgE+VeNx0ihYiAj18
|
||||||
|
1s4cqbbI+73/vp/03k4odjuztFq1hMzQdI0E/ntD24GGdinRGnhlZfb7OpwIzpzC
|
||||||
|
kR5Qi+XsTn9K0eFBppfcykcW8YDtxFXjZH4za99chRbZY/N3/2EilMgCPSgNBOIf
|
||||||
|
XiGaQr/LAgMBAAECggEAPbdRPi+L8CvsS3x7tUNB9wANsFOFVCOdkaqfq3w/PJ/C
|
||||||
|
KSlharzsLzHjjaCh3KzKB0KoJkfbrrgo0i5uMRIeVcZ2VAToMFiUAMxLepa7DID6
|
||||||
|
ZWanKbyFEi32aS1axz6edCh7QLx/aF8PLCewAb4bCklSGbqUkEffvVdpgkmkKdST
|
||||||
|
YthPC5k1BMIHxQr7L4AZaZkyep8hSz8eufukVrwEK9VRQfvh8p756AEuScl89En/
|
||||||
|
xsWviSysLeGeRqPS+DnGBrqTAb3Q3MRLcAmChA0TRy5bLk52YqPpS7Emo4dlMfX7
|
||||||
|
NRAkkViifzlLFkQS+G7ZYv4zc8gg+IOK2dPrnqtWDQKBgQD0TKQi9Mq2FM9NcBDO
|
||||||
|
FAb19BY/25q27WWuuiJl95bUbtV07SquymDhVblVr+SuYum6dsnhsQJkP1FpbL3B
|
||||||
|
c4CQ43WCOpAdPF2fp/69bxx14uffYqiiUhgBbr6kIGyLCkvVCTURRXZL91oO5gs/
|
||||||
|
2wcmwBOIdTeemCaJtuuJwoYl3wKBgQDzMC4jC6mOmZHocfXJNm0fht0ElJ9SAndL
|
||||||
|
CY6Z3DLPq6RZUE/ciSqUwR//geTbnahiy6/3oUXjM/UINgJTjRm6YHoqWawYR0W4
|
||||||
|
b+fox0uuSH5kjiW5oMU5Bg0SOfJjHW/GnXUe9JDwcS3YwVn9oPt2UuliPtzLYHVj
|
||||||
|
2jEp4fXrlQKBgQDjksmL7rEvMO9z2aMt9aYOVBSt4+qZ4UfJnocQqbWNqrmZtJ0A
|
||||||
|
OnJJNsvxMGs8r9O+6Y1ierwZmopCRRP3M5teXSVH7Tn2ohcs9Rfua6T9hCQwCf3B
|
||||||
|
R+wo2Xsp9TJny22cxHj039o1JfR00INGNsjQpjkL8vWe/WlY/Fcp+1VvzQKBgE4y
|
||||||
|
EtO//0BUDv+QDTkq4AHAKrc7VtNW6abeJtVAYbI2/byeP1+pV2DHjJNq3/zh/+/s
|
||||||
|
kONuHvvEjCicvTjCaSBtvzp45QZVfIympwpJcwNSWhnZPzYmBOSmFnPi4BaQs41I
|
||||||
|
ug0/FI/LxLMq0NXl+pV8aYDmt7ZJiNWXpjFSb/HVAoGBAIb1hSlU2a02lNGxRHy9
|
||||||
|
fx/QePF9KyWqMzUkP2vIKgZQynZyM0RXFzSCS+kcHMVPexcInSxLSXk+cdz4v4un
|
||||||
|
w25dSvFU/SuuGZJHIfTQaYVRE9DJ3MzmjAZ4iA4ZFRX+FDbd45IOifreVuxcsDGX
|
||||||
|
gArpxkeiASRBUzcum5F5AV8P
|
||||||
|
-----END PRIVATE KEY-----
|
52
ManagementApp/ManagementApp.csproj
Normal file
52
ManagementApp/ManagementApp.csproj
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
|
||||||
|
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Dapper" Version="2.1.35" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="8.0.6" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="8.0.6" />
|
||||||
|
<PackageReference Include="Microsoft.Graph" Version="5.56.0" />
|
||||||
|
<PackageReference Include="Microsoft.Identity.Web" Version="3.0.1" />
|
||||||
|
<PackageReference Include="MySqlConnector" Version="2.3.7" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\AppLibs\AppLibs\AppLibs.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Update="wwwroot\css\atg-font\atg-admin-font.css">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Update="wwwroot\js\ext_libs\js-AOverScroll.js">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Update="wwwroot\js\libs\js-AMenu.js">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Update="wwwroot\js\libs\js-core.js">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Update="Keys\key.pfx">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Cert\MApp.pfx">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
12
ManagementApp/Models/IPaging.cs
Normal file
12
ManagementApp/Models/IPaging.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
namespace ManagementApp.Models
|
||||||
|
{
|
||||||
|
public interface IPaging
|
||||||
|
{
|
||||||
|
bool IsFirstQuery { set; get; }
|
||||||
|
int PageSize { set; get; }
|
||||||
|
|
||||||
|
int PageNumber { set; get; }
|
||||||
|
|
||||||
|
int MaxRow { set; get; }
|
||||||
|
}
|
||||||
|
}
|
17
ManagementApp/Models/MessageHeader.cs
Normal file
17
ManagementApp/Models/MessageHeader.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
namespace ManagementApp.Models
|
||||||
|
{
|
||||||
|
public class MessageHeader
|
||||||
|
{
|
||||||
|
public int ID { set; get; }
|
||||||
|
|
||||||
|
public string Message { set; get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Return Message Status
|
||||||
|
/// 0 is Error
|
||||||
|
/// 1 is Success
|
||||||
|
/// </summary>
|
||||||
|
public int Status { set; get; }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
17
ManagementApp/Models/ModelBase.cs
Normal file
17
ManagementApp/Models/ModelBase.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
namespace ManagementApp.Models
|
||||||
|
{
|
||||||
|
public abstract class ModelBase: IPaging
|
||||||
|
{
|
||||||
|
public abstract Task<MessageHeader> AddAsync();
|
||||||
|
|
||||||
|
public abstract Task<MessageHeader> UpdateAsync();
|
||||||
|
|
||||||
|
public abstract Task<MessageHeader> DeleteAsync();
|
||||||
|
public bool IsFirstQuery { set; get; }
|
||||||
|
public int PageSize { get; set; }
|
||||||
|
public int PageNumber { get; set; }
|
||||||
|
public int MaxRow { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
75
ManagementApp/Models/Services/Microsoft365Service.cs
Normal file
75
ManagementApp/Models/Services/Microsoft365Service.cs
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
using Azure.Identity;
|
||||||
|
using Microsoft.Graph;
|
||||||
|
using Microsoft.Graph.Models;
|
||||||
|
using Microsoft.Kiota.Abstractions;
|
||||||
|
using System.IO.Pipes;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Web;
|
||||||
|
|
||||||
|
namespace ManagementApp.Models.Services
|
||||||
|
{
|
||||||
|
public class Microsoft365Service
|
||||||
|
{
|
||||||
|
|
||||||
|
public int Status { set; get; } = -1;
|
||||||
|
|
||||||
|
private GraphServiceClient graphClient;
|
||||||
|
private string tenantID;
|
||||||
|
private string clientID;
|
||||||
|
private string[] scope;
|
||||||
|
private string clientSecret;
|
||||||
|
private string secretID;
|
||||||
|
private Date secretExpiresDate;
|
||||||
|
public string Host { set; get; }
|
||||||
|
public Microsoft365Service() {
|
||||||
|
this.clientID = "10012dab-5561-4cef-9b7a-a7f2c0bea704";
|
||||||
|
this.tenantID = "8c8a0bb8-9582-4322-b9fc-11d031e5702a";
|
||||||
|
this.scope = new[] { "https://graph.microsoft.com/.default" };
|
||||||
|
this.clientSecret = "RRi8Q~CvY1GmY8~zKDGv6bdeBSyVvAHy4nOcCcKd";
|
||||||
|
this.secretID = "d1b4e1a0-faae-42c1-b5e4-c4a26a345c5c";
|
||||||
|
this.secretExpiresDate = new Date(2025, 8, 12);
|
||||||
|
this.Host = string.Empty;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Message { get; set; } = "";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public async Task<UserCollectionResponse?> GetUser()
|
||||||
|
{
|
||||||
|
var users = await graphClient.Users.GetAsync(u => { u.QueryParameters.Select = ["displayName", "jobTitle"]; });
|
||||||
|
return users;
|
||||||
|
}
|
||||||
|
public async Task<SiteCollectionResponse?> GetDrives()
|
||||||
|
{
|
||||||
|
var sites = await graphClient.Sites.GetAsync();
|
||||||
|
var siteInfor = (sites != null) ? sites.Value.Where(a => a.IsPersonalSite == false && a.DisplayName == "Storage Backup").FirstOrDefault() : null;
|
||||||
|
|
||||||
|
|
||||||
|
//graphClient.Sites[""].Drives.GetAsync()
|
||||||
|
return sites;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<string> ConnectMicrosoft365()
|
||||||
|
{
|
||||||
|
await Task.Run(() =>
|
||||||
|
{
|
||||||
|
var options = new ClientSecretCredentialOptions
|
||||||
|
{
|
||||||
|
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
|
||||||
|
};
|
||||||
|
|
||||||
|
var clientSecretCredential = new ClientSecretCredential(
|
||||||
|
this.tenantID, this.clientID, clientSecret, options);
|
||||||
|
|
||||||
|
this.graphClient = new GraphServiceClient(clientSecretCredential, this.scope);
|
||||||
|
this.Status = 0;
|
||||||
|
});
|
||||||
|
return "OK";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
113
ManagementApp/Models/TypeStorageServerModel.cs
Normal file
113
ManagementApp/Models/TypeStorageServerModel.cs
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
using Dapper;
|
||||||
|
using ManagementApp.Dapper.AExtentions;
|
||||||
|
using ManagementApp.DBModels;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using MySqlConnector;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Data.Common;
|
||||||
|
|
||||||
|
namespace ManagementApp.Models
|
||||||
|
{
|
||||||
|
public class TypeStorageServerModel: ModelBase, IPaging
|
||||||
|
{
|
||||||
|
public int ID { set; get; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public override async Task<MessageHeader> AddAsync()
|
||||||
|
{
|
||||||
|
var f = new MessageHeader();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var con = new MySqlConnection(DBManagement.GetConnectionString()))
|
||||||
|
{
|
||||||
|
await con.OpenAsync();
|
||||||
|
await con.Insert(new TypeStorageServer { TypeName = Name });
|
||||||
|
}
|
||||||
|
f.Status = 1;
|
||||||
|
f.Message = "OK";
|
||||||
|
}
|
||||||
|
catch(DbException ex)
|
||||||
|
{
|
||||||
|
f.Status = 0;
|
||||||
|
f.Message = ex.Message;
|
||||||
|
f.ID = 1001;
|
||||||
|
}
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Task<MessageHeader> DeleteAsync()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task<MessageHeader> UpdateAsync()
|
||||||
|
{
|
||||||
|
var f = new MessageHeader();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var con = new MySqlConnection(DBManagement.GetConnectionString()))
|
||||||
|
{
|
||||||
|
await con.OpenAsync();
|
||||||
|
await con.Update(new TypeStorageServer { IdTypeStorageServer = ID, TypeName = Name });
|
||||||
|
}
|
||||||
|
f.Status = 1;
|
||||||
|
f.Message = "OK";
|
||||||
|
}
|
||||||
|
catch (DbException ex)
|
||||||
|
{
|
||||||
|
f.Status = 0;
|
||||||
|
f.Message = ex.Message;
|
||||||
|
f.ID = 1002;
|
||||||
|
}
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> GetTypeStoragesAsync()
|
||||||
|
{
|
||||||
|
using (var con = new MySqlConnection(DBManagement.GetConnectionString()))
|
||||||
|
{
|
||||||
|
await con.OpenAsync();
|
||||||
|
if (IsFirstQuery)
|
||||||
|
{
|
||||||
|
using (var multi = await con
|
||||||
|
.QueryMultipleAsync("SELECT COUNT(*) FROM TypeStorageServer;" +
|
||||||
|
"SELECT * FROM TypeStorageServer ORDER BY idTypeStorageServer DESC " +
|
||||||
|
"OFFSET @Offset ROWS FETCH NEXT @PageSize ROWS ONLY", new { Offset = (PageNumber - 1) * PageSize, PageSize = this.PageSize }))
|
||||||
|
{
|
||||||
|
int maxRow = await multi.ReadSingleAsync<int>();
|
||||||
|
IEnumerable<TypeStorageServer> types = await multi.ReadAsync<TypeStorageServer>();
|
||||||
|
return new JsonResult(new
|
||||||
|
{
|
||||||
|
mrows = maxRow,
|
||||||
|
data = JsonConvert.SerializeObject(types)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IEnumerable<TypeStorageServer> t = (await con
|
||||||
|
.QueryAsync<TypeStorageServer>("SELECT * FROM TypeStorageServer ORDER BY idTypeStorageServer DESC " +
|
||||||
|
"OFFSET @Offset ROWS FETCH NEXT @PageSize ROWS ONLY", new { Offset = (PageNumber - 1) * PageSize, PageSize = this.PageSize }));
|
||||||
|
return new JsonResult(new
|
||||||
|
{
|
||||||
|
data = JsonConvert.SerializeObject(t)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task<IActionResult> GetAllTypeStorage()
|
||||||
|
{
|
||||||
|
using (var con = new MySqlConnection(DBManagement.GetConnectionString()))
|
||||||
|
{
|
||||||
|
IEnumerable<dynamic> t = await con
|
||||||
|
.QueryAsync("SELECT idTypeStorageServer AS ID, TypeName AS Type FROM TypeStorageServer ORDER BY idTypeStorageServer ASC");
|
||||||
|
return new JsonResult(new
|
||||||
|
{
|
||||||
|
data = JsonConvert.SerializeObject(t)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
117
ManagementApp/Models/ValidationDomainModel.cs
Normal file
117
ManagementApp/Models/ValidationDomainModel.cs
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
|
||||||
|
using Dapper;
|
||||||
|
using ManagementApp.Dapper.AExtentions;
|
||||||
|
using ManagementApp.DBModels;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using MySqlConnector;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.Data.Common;
|
||||||
|
|
||||||
|
namespace ManagementApp.Models
|
||||||
|
{
|
||||||
|
public class ValidationDomainModel: ModelBase
|
||||||
|
{
|
||||||
|
public int ID { set; get; }
|
||||||
|
|
||||||
|
public int PortNumber { set; get; }
|
||||||
|
|
||||||
|
public string Protocol { set; get; }
|
||||||
|
|
||||||
|
public string Name { set; get; }
|
||||||
|
|
||||||
|
public override async Task<MessageHeader> AddAsync()
|
||||||
|
{
|
||||||
|
var f = new MessageHeader();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var con = new MySqlConnection(DBManagement.GetConnectionString()))
|
||||||
|
{
|
||||||
|
await con.OpenAsync();
|
||||||
|
await con.Insert(new ValidationDomain { DomainName = Name, PortNumber = this.PortNumber, Protocol = this.Protocol });
|
||||||
|
}
|
||||||
|
f.Status = 1;
|
||||||
|
f.Message = "OK";
|
||||||
|
}
|
||||||
|
catch (DbException ex)
|
||||||
|
{
|
||||||
|
f.Status = 0;
|
||||||
|
f.Message = ex.Message;
|
||||||
|
f.ID = 61031;
|
||||||
|
}
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
public async Task<IActionResult> GetValidationDomainAsync()
|
||||||
|
{
|
||||||
|
using (var con = new MySqlConnection(DBManagement.GetConnectionString()))
|
||||||
|
{
|
||||||
|
await con.OpenAsync();
|
||||||
|
if (IsFirstQuery)
|
||||||
|
{
|
||||||
|
using (var multi = await con
|
||||||
|
.QueryMultipleAsync("SELECT COUNT(*) FROM ValidationDomain;" +
|
||||||
|
"SELECT * FROM ValidationDomain ORDER BY idValidationDomain DESC " +
|
||||||
|
"OFFSET @Offset ROWS FETCH NEXT @PageSize ROWS ONLY", new { Offset = (PageNumber - 1) * PageSize, PageSize = this.PageSize }))
|
||||||
|
{
|
||||||
|
int maxRow = await multi.ReadSingleAsync<int>();
|
||||||
|
IEnumerable<ValidationDomain> types = await multi.ReadAsync<ValidationDomain>();
|
||||||
|
return new JsonResult(new
|
||||||
|
{
|
||||||
|
mrows = maxRow,
|
||||||
|
data = JsonConvert.SerializeObject(types)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IEnumerable<ValidationDomain> t = (await con
|
||||||
|
.QueryAsync<ValidationDomain>("SELECT * FROM ValidationDomain ORDER BY idValidationDomain DESC " +
|
||||||
|
"OFFSET @Offset ROWS FETCH NEXT @PageSize ROWS ONLY", new { Offset = (PageNumber - 1) * PageSize, PageSize = this.PageSize }));
|
||||||
|
return new JsonResult(new
|
||||||
|
{
|
||||||
|
data = JsonConvert.SerializeObject(t)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public override Task<MessageHeader> DeleteAsync()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task<MessageHeader> UpdateAsync()
|
||||||
|
{
|
||||||
|
var f = new MessageHeader();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var con = new MySqlConnection(DBManagement.GetConnectionString()))
|
||||||
|
{
|
||||||
|
await con.OpenAsync();
|
||||||
|
await con.Update(new ValidationDomain { IdValidationDomain = ID, DomainName = Name, PortNumber = this.PortNumber, Protocol = this.Protocol });
|
||||||
|
}
|
||||||
|
f.Status = 1;
|
||||||
|
f.Message = "OK";
|
||||||
|
}
|
||||||
|
catch (DbException ex)
|
||||||
|
{
|
||||||
|
f.Status = 0;
|
||||||
|
f.Message = ex.Message;
|
||||||
|
f.ID = 61032;
|
||||||
|
}
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task<IActionResult> GetAllValidationDomain()
|
||||||
|
{
|
||||||
|
using (var con = new MySqlConnection(DBManagement.GetConnectionString()))
|
||||||
|
{
|
||||||
|
await con.OpenAsync();
|
||||||
|
IEnumerable<dynamic> t = (await con
|
||||||
|
.QueryAsync("SELECT IDValidationDomain As ID, DomainName As Name FROM ValidationDomain ORDER BY idValidationDomain DESC"));
|
||||||
|
return new JsonResult(new
|
||||||
|
{
|
||||||
|
data = JsonConvert.SerializeObject(t)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
49
ManagementApp/Program.cs
Normal file
49
ManagementApp/Program.cs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
using AppLibs;
|
||||||
|
using AppLibs.Libs;
|
||||||
|
using ManagementApp.Models.Services;
|
||||||
|
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||||||
|
|
||||||
|
await WSNavigation.LoadJson().ConfigureAwait(false);
|
||||||
|
|
||||||
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
|
// Add services to the container.
|
||||||
|
//builder.Services.AddCors(o => o.AddPolicy(name: "allowOrigins",
|
||||||
|
// p => {
|
||||||
|
// p.WithOrigins("https://login.microsoftonline.com", "https://aadcdn.msftauth.net").SetIsOriginAllowed(o => true).AllowAnyHeader().AllowAnyMethod().AllowCredentials();
|
||||||
|
// })
|
||||||
|
//);
|
||||||
|
|
||||||
|
#if (!DEBUG)
|
||||||
|
builder.WebHost.UseKestrel(o =>
|
||||||
|
{
|
||||||
|
o.ListenAnyIP(5103, lo =>
|
||||||
|
{
|
||||||
|
lo.Protocols = HttpProtocols.Http1AndHttp2AndHttp3;
|
||||||
|
lo.UseHttps(CertificateStore.GetHTTPSCertificate("Cert/MApp.pfx"), "Pgq95b7r");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
builder.Services.AddControllersWithViews();
|
||||||
|
#else
|
||||||
|
builder.Services.AddControllersWithViews().AddRazorRuntimeCompilation();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
builder.Services.AddSingleton<Microsoft365Service>(s => new Microsoft365Service());
|
||||||
|
var app = builder.Build();
|
||||||
|
|
||||||
|
// Configure the HTTP request pipeline.
|
||||||
|
if (!app.Environment.IsDevelopment())
|
||||||
|
{
|
||||||
|
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.UseRouting();
|
||||||
|
|
||||||
|
app.MapControllerRoute(
|
||||||
|
name: "default",
|
||||||
|
pattern: "{controller=Home}/{action=Index}/{id?}");
|
||||||
|
app.Run();
|
38
ManagementApp/Properties/launchSettings.json
Normal file
38
ManagementApp/Properties/launchSettings.json
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
{
|
||||||
|
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||||
|
"iisSettings": {
|
||||||
|
"windowsAuthentication": false,
|
||||||
|
"anonymousAuthentication": true,
|
||||||
|
"iisExpress": {
|
||||||
|
"applicationUrl": "http://localhost:57971",
|
||||||
|
"sslPort": 44322
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"profiles": {
|
||||||
|
"http": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"launchBrowser": true,
|
||||||
|
"applicationUrl": "http://localhost:5158",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"https": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"launchBrowser": true,
|
||||||
|
"applicationUrl": "https://localhost:7271;http://localhost:5158",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"IIS Express": {
|
||||||
|
"commandName": "IISExpress",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
5
ManagementApp/Views/Home/Index.cshtml
Normal file
5
ManagementApp/Views/Home/Index.cshtml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
<div class="text-center">
|
||||||
|
<h1 class="display-4">Welcome</h1>
|
||||||
|
<p>Learn about <a href="https://learn.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
|
||||||
|
</div>
|
6
ManagementApp/Views/Home/Privacy.cshtml
Normal file
6
ManagementApp/Views/Home/Privacy.cshtml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
@{
|
||||||
|
ViewData["Title"] = "Privacy Policy";
|
||||||
|
}
|
||||||
|
<h1>@ViewData["Title"]</h1>
|
||||||
|
|
||||||
|
<p>Use this page to detail your site's privacy policy.</p>
|
43
ManagementApp/Views/Login/Index.cshtml
Normal file
43
ManagementApp/Views/Login/Index.cshtml
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<div class="c">
|
||||||
|
<div class="r j-c-center h-100vh pt-5 pb-5">
|
||||||
|
<div class="c-s-12 c-m-10 c-l-8 c-x-10 c-sx-8 w-login mt-auto mb-auto">
|
||||||
|
<div class="r-n-g j-c-center a-i-center">
|
||||||
|
<div class="d-n c-x-6 d-x-b">
|
||||||
|
<img src="~/images/img1.jpg" class="w-100" />
|
||||||
|
</div>
|
||||||
|
<div class="c-12 c-x-6">
|
||||||
|
<div class="h-100 d-f a-i-center">
|
||||||
|
<div class="ws-login d-f f-c a-i-center">
|
||||||
|
<span class="ws-title">Đăng Nhập</span>
|
||||||
|
<div class="ws-input mb-4">
|
||||||
|
<span class="label-input">Tài khoản</span>
|
||||||
|
<div class="c-input d-f a-i-center">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M313.6 304c-28.7 0-42.5 16-89.6 16-47.1 0-60.8-16-89.6-16C60.2 304 0 364.2 0 438.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-25.6c0-74.2-60.2-134.4-134.4-134.4zM400 464H48v-25.6c0-47.6 38.8-86.4 86.4-86.4 14.6 0 38.3 16 89.6 16 51.7 0 74.9-16 89.6-16 47.6 0 86.4 38.8 86.4 86.4V464zM224 288c79.5 0 144-64.5 144-144S303.5 0 224 0 80 64.5 80 144s64.5 144 144 144zm0-240c52.9 0 96 43.1 96 96s-43.1 96-96 96-96-43.1-96-96 43.1-96 96-96z" /></svg>
|
||||||
|
<input type="text" class="input" placeholder="Nhập tài khoản" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="ws-input">
|
||||||
|
<span class="label-input">Mật khẩu</span>
|
||||||
|
<div class="c-input d-f a-i-center">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M400 224h-24v-72C376 68.2 307.8 0 224 0S72 68.2 72 152v72H48c-26.5 0-48 21.5-48 48v192c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V272c0-26.5-21.5-48-48-48zM264 392c0 22.1-17.9 40-40 40s-40-17.9-40-40v-48c0-22.1 17.9-40 40-40s40 17.9 40 40v48zm32-168H152v-72c0-39.7 32.3-72 72-72s72 32.3 72 72v72z" /></svg>
|
||||||
|
<input type="password" class="input" placeholder="Nhập mật khẩu" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="ws-forgot ml-auto">
|
||||||
|
<a href="#">Quên mật khẩu?</a>
|
||||||
|
</div>
|
||||||
|
<div class="ws-btn d-f j-c-center">
|
||||||
|
<div class="btn-mask"></div>
|
||||||
|
<button class="btn btn-effect">Đăng nhập</button>
|
||||||
|
</div>
|
||||||
|
<div class="ws-signup d-f f-c a-i-center">
|
||||||
|
<span>Đăng ký tài khoản bằng ID</span>
|
||||||
|
<a href="#">Đăng Ký</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
44
ManagementApp/Views/Partial/MenuAP.cshtml
Normal file
44
ManagementApp/Views/Partial/MenuAP.cshtml
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
@using AppLibs.Libs
|
||||||
|
@{
|
||||||
|
List<NavItem> t = WSNavigation.GetListMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
@foreach (var i in t)
|
||||||
|
{
|
||||||
|
|
||||||
|
@if (i.IsGroup)
|
||||||
|
{
|
||||||
|
<div class="nav-header">
|
||||||
|
@i.Name
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
else if (i.SubItem == null)
|
||||||
|
{
|
||||||
|
<a class="nav-i d-f" href="javascript:void(0)" app-url="@i.Url" app-nav nav-id="@i.ID">
|
||||||
|
<span class="atg atg-@i.Icon mr-2">
|
||||||
|
</span>
|
||||||
|
<span>@i.Name</span>
|
||||||
|
</a>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<div class="nav-i has-sub d-f f-c" data-dropdown>
|
||||||
|
<a class="nav-i d-f" href="javascript:void(0)">
|
||||||
|
<span class="atg atg-@i.Icon mr-2">
|
||||||
|
</span>
|
||||||
|
<span>@i.Name</span>
|
||||||
|
<div class="more"><span class="atg atg-more"></span></div>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div class="sub-item d-f f-c">
|
||||||
|
@foreach (var j in i.SubItem)
|
||||||
|
{
|
||||||
|
<a class="nav-i d-f nonhide" href="javascript:void(0)" app-url="@j.Url" app-nav nav-id="@j.ID" nav-sub>
|
||||||
|
<span class="atg atg-circle mr-2"></span>
|
||||||
|
<span>@j.Name</span>
|
||||||
|
</a>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
1
ManagementApp/Views/Rooms/Add.cshtml
Normal file
1
ManagementApp/Views/Rooms/Add.cshtml
Normal file
@ -0,0 +1 @@
|
|||||||
|
Rooms Add
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user