2 Commits
v0.0.0 ... main

Author SHA1 Message Date
1e635f53bf 09/06 2025-06-09 09:50:54 +07:00
5beb66f11a first 2025-06-04 14:17:32 +07:00
257 changed files with 72824 additions and 2 deletions

63
.gitattributes vendored Normal file
View 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
View 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

View 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>

View File

@ -0,0 +1,11 @@
namespace AppLibs.Libs
{
public class CertificateStore
{
public static string GetHTTPSCertificate(string name)
{
var str = Path.GetFullPath(name);
return str;
}
}
}

View 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();
}
}
}
}

View 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;
}
}
}

View 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();
}
}
}

View 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");
}
}
}

View 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;
}
}
}
}

View 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("");
}
}
}
}

View 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;
}
}
}
}

View 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"; } }
}
}

View 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" };
}
}
}

View 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();
}
}

View 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;
}
}
}

View 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"
}

View 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'
}

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View 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
}

View 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
}

File diff suppressed because one or more lines are too long

View 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}

View 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)
}

View 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
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View 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;
}
}

View 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();
}
}
}
}

View 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;
}
}

View 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() {
}
}

View 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" });
}
}

View 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));
}
}

View 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;
}
}

View 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();
}
}
}

View 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&nbsp";
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 = "&nbsp/&nbsp";
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;
}
}

View 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];
}
}
}
}

View 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();
}
}

View 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");
}
}

View 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", "");
}
}

View 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);
}
}

View 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);
}
}

View 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);
});
}
}

View 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
}
}
};

View 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);

File diff suppressed because it is too large Load Diff

View 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);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

BIN
Database Diagram/db.mwb Normal file

Binary file not shown.

BIN
Database Diagram/db.mwb.bak Normal file

Binary file not shown.

View File

@ -0,0 +1,12 @@
{
"version": 1,
"isRoot": true,
"tools": {
"dotnet-ef": {
"version": "8.0.6",
"commands": [
"dotnet-ef"
]
}
}
}

View File

@ -0,0 +1,6 @@
namespace ManagementApp.AServices.Microsoft365
{
public interface IMicrosoft365
{
}
}

View File

@ -0,0 +1,11 @@
namespace ManagementApp.AServices.Microsoft365
{
public class Microsoft365: IMicrosoft365
{
public Microsoft365()
{
}
}
}

View 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; } = "";
}
}

View File

@ -0,0 +1,6 @@
namespace ManagementApp.AServices.Microsoft365
{
public class SharePointOption
{
}
}

View 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();
}
}
}

View File

@ -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();
}
}
}

View File

@ -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);
}
}
}

View 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);
}
}

View 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();
}
}
}

View 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();
}
}
}

View 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() } );
}
}
}

View 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");
}
}
}

View 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;
}
}
}

View 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;
}
}
}

View 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;
}
}
}

View 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;
}
}
}

View 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;
}
}
}

View 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": ""
}
]

View 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-----

View 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-----

View 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-----

View 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-----

View 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-----

View 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-----

View 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-----

View 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>

View 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; }
}
}

View 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; }
}
}

View 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; }
}
}

View 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";
}
}
}

View 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)
});
}
}
}
}

View 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
View 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();

View 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"
}
}
}
}

View 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>

View 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>

View 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>

View 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>
}
}

View File

@ -0,0 +1 @@
Rooms Add

Some files were not shown because too many files have changed in this diff Show More