update v0.0.2 twa sys
This commit is contained in:
@ -1,6 +1,7 @@
|
||||
using AppLibs.Libs;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using TWASys_App.Models;
|
||||
|
||||
namespace TWASys_App.Controllers
|
||||
{
|
||||
@ -13,5 +14,37 @@ namespace TWASys_App.Controllers
|
||||
{
|
||||
return await this.ViewAsync();
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> SignIn([FromForm] UserModel user)
|
||||
{
|
||||
if (user.Username is not null && user.Password is not null && user.Username.Length > 0 && user.Password.Length > 0)
|
||||
{
|
||||
await Task.Delay(100);
|
||||
if (user.Username.ToLower().Equals("admin") && user.Password.Equals("TWA@2025"))
|
||||
{
|
||||
HttpContext.Session.SetString("userID", "admin");
|
||||
return Json(new MessageHeader
|
||||
{
|
||||
ID = 10003,
|
||||
Message = "Login Success",
|
||||
Status = 1
|
||||
});
|
||||
}
|
||||
return Json(new MessageHeader
|
||||
{
|
||||
ID = 10002,
|
||||
Message = "The username or password you entered is incorrect",
|
||||
Status = 0
|
||||
});
|
||||
}
|
||||
return Json(new MessageHeader
|
||||
{
|
||||
ID = 10001,
|
||||
Message = "The username and password are required",
|
||||
Status = 0
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,6 +67,12 @@ namespace TWASys_App.Controllers
|
||||
return await TypeStorageServerModel.GetAllTypeStorage();
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> GetStorage([FromForm] StorageModel model)
|
||||
{
|
||||
return await model.GetStorages();
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> GetValidationDomain()
|
||||
{
|
||||
@ -85,6 +91,13 @@ namespace TWASys_App.Controllers
|
||||
return Json(await model.AddAsync());
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> UpdateStorageSize([FromForm] StorageModel model)
|
||||
{
|
||||
|
||||
return Json(await model.UpdateStorageSize());
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> GenerationAccessToken()
|
||||
{
|
||||
@ -116,6 +129,19 @@ namespace TWASys_App.Controllers
|
||||
});
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> CheckStorageInit()
|
||||
{
|
||||
await Task.Delay(1);
|
||||
var f = System.IO.File.Exists(System.IO.Path.GetFullPath("Json/dataServer.json"));
|
||||
return Json(new MessageHeader
|
||||
{
|
||||
ID= 61011,
|
||||
Message=f?"has":"no",
|
||||
Status=1
|
||||
});
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> GetSysInfo()
|
||||
{
|
||||
|
||||
@ -17,5 +17,8 @@ namespace TWASys_App.DBModels
|
||||
|
||||
[NotMapped()]
|
||||
public ICollection<ServerAuthorization_has_Token> Tokens { get; set; } = new List<ServerAuthorization_has_Token>();
|
||||
|
||||
[NotMapped()]
|
||||
public ICollection<RefreshToken> RefreshTokens { get; set; } = new List<RefreshToken>();
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,9 +17,12 @@ namespace TWASys_App.DBModels
|
||||
|
||||
public DateTime? CreateDate { get; set; }
|
||||
|
||||
|
||||
public int? Size { get; set; } = null;
|
||||
public string ControllerID { get; set; } = "";
|
||||
|
||||
public int Status { get; set; } = 0;
|
||||
|
||||
[NotMapped]
|
||||
public TypeStorageServer TypeStorageServer { set; get; } = null!;
|
||||
}
|
||||
}
|
||||
|
||||
3
TWASys-App/Json/dataServer1.json
Normal file
3
TWASys-App/Json/dataServer1.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
|
||||
}
|
||||
@ -46,7 +46,7 @@
|
||||
},
|
||||
{
|
||||
"id": "8000",
|
||||
"name": "Rooms Management",
|
||||
"name": "Website Management",
|
||||
"icon": "",
|
||||
"group": 1,
|
||||
"url": "",
|
||||
|
||||
@ -1,7 +1,11 @@
|
||||
|
||||
using AppLibs.Libs;
|
||||
using Dapper;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Razor.Language.Intermediate;
|
||||
using Microsoft.VisualBasic;
|
||||
using MySqlConnector;
|
||||
using Newtonsoft.Json;
|
||||
using System.Data.Common;
|
||||
using System.Xml.Linq;
|
||||
using TWASys_App.Dapper.AExtentions;
|
||||
@ -11,6 +15,7 @@ namespace TWASys_App.Models
|
||||
{
|
||||
public class StorageModel : ModelBase
|
||||
{
|
||||
public long IdStorageServer { set; get; }
|
||||
public long StorageTypeID { set; get; }
|
||||
|
||||
public string ControllerName { set; get; } = "";
|
||||
@ -19,6 +24,7 @@ namespace TWASys_App.Models
|
||||
|
||||
public ICollection<ValidationDomain> ValidationDomains { set; get; } = new List<ValidationDomain>();
|
||||
|
||||
public int Size { set; get; };
|
||||
public string IpPublic { set; get; } = "";
|
||||
|
||||
public string IpPrivatev4 { set; get; } = "";
|
||||
@ -54,6 +60,45 @@ namespace TWASys_App.Models
|
||||
|
||||
public string RTokenValue { set; get; } = "";
|
||||
|
||||
public async Task<IActionResult> GetStorages(int status = 0)
|
||||
{
|
||||
await using (var con = new MySqlConnection(DBManagement.GetConnectionString()))
|
||||
{
|
||||
string sql = @"
|
||||
WITH d AS (
|
||||
SELECT *
|
||||
FROM StorageServer
|
||||
WHERE status = @status
|
||||
ORDER BY idStorageServer
|
||||
LIMIT @PageSize OFFSET @Offset)
|
||||
SELECT d.*,t.typeName FROM d
|
||||
JOIN TypeStorageServer t ON t.idTypeStorageServer = d.idTypeStorageServer;
|
||||
";
|
||||
await con.OpenAsync();
|
||||
if (IsFirstQuery)
|
||||
{
|
||||
await using (var multi = await con
|
||||
.QueryMultipleAsync("SELECT COUNT(*) FROM StorageServer;" + sql, new { Offset = (PageNumber - 1) * PageSize, PageSize = this.PageSize, status = status }))
|
||||
{
|
||||
int maxRow = await multi.ReadSingleAsync<int>();
|
||||
var types = await multi.ReadAsync();
|
||||
return new JsonResult(new
|
||||
{
|
||||
mrows = maxRow,
|
||||
data = JsonConvert.SerializeObject(types)
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var t = (await con.QueryAsync(sql, new { Offset = (PageNumber - 1) * PageSize, PageSize = this.PageSize, status = status }));
|
||||
return new JsonResult(new
|
||||
{
|
||||
data = JsonConvert.SerializeObject(t)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
public override async Task<MessageHeader> AddAsync()
|
||||
{
|
||||
await using var con = new MySqlConnector.MySqlConnection(DBManagement.GetConnectionString(true));
|
||||
@ -114,6 +159,12 @@ namespace TWASys_App.Models
|
||||
ExpireDate = DateTime.UtcNow.AddMonths(3),
|
||||
Status = 0
|
||||
};
|
||||
var ssAT = new ServerAuthorization_has_Token
|
||||
{
|
||||
IdToken = TokenID,
|
||||
Count = 1,
|
||||
Status = 0
|
||||
};
|
||||
var rT = new RefreshToken
|
||||
{
|
||||
IdRefreshToken = RTokenID,
|
||||
@ -129,6 +180,7 @@ namespace TWASys_App.Models
|
||||
bi.AddRow(ss_lc);
|
||||
bi.AddRow(serverAuthorization);
|
||||
bi.AddRow(token);
|
||||
bi.AddRow(ssAT);
|
||||
bi.AddRow(rT);
|
||||
await bi.ExcuteQuery();
|
||||
await trans.CommitAsync();
|
||||
@ -155,5 +207,73 @@ namespace TWASys_App.Models
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public async Task<MessageHeader> UpdateStorageSize()
|
||||
{
|
||||
var fMess = new MessageHeader();
|
||||
string sql = @"UPDATE StorageServer
|
||||
SET Size = @size
|
||||
Where idStorageServer = @idStorage;
|
||||
WITH sa_need AS (
|
||||
SELECT idServerAuthorization
|
||||
FROM ServerAuthorization
|
||||
WHERE idStorageServer = @idStorage
|
||||
),
|
||||
maxc AS (
|
||||
SELECT idServerAuthorization, MAX(`count`) AS max_count
|
||||
FROM ServerAuthorization_has_Token
|
||||
WHERE idServerAuthorization IN (SELECT idServerAuthorization FROM sa_need)
|
||||
GROUP BY idServerAuthorization
|
||||
)
|
||||
SELECT
|
||||
sa.idServerAuthorization,
|
||||
st.idToken,
|
||||
t.accessToken
|
||||
FROM sa_need sa
|
||||
JOIN maxc m ON m.idServerAuthorization = sa.idServerAuthorization
|
||||
JOIN ServerAuthorization_has_Token st
|
||||
ON st.idServerAuthorization = sa.idServerAuthorization AND st.`count` = m.max_count
|
||||
LEFT JOIN Token t ON t.idToken = st.idToken;
|
||||
WITH sa_need AS (
|
||||
SELECT idServerAuthorization
|
||||
FROM ServerAuthorization
|
||||
WHERE idStorageServer = @idStorage)
|
||||
SELECT r.*
|
||||
FROM sa_need s
|
||||
JOIN RefreshToken r
|
||||
ON r.idServerAuthorization = s.idServerAuthorization
|
||||
WHERE r.idRefreshToken = (
|
||||
SELECT r2.idRefreshToken
|
||||
FROM RefreshToken r2
|
||||
WHERE r2.idServerAuthorization = s.idServerAuthorization and r2.status = 0
|
||||
ORDER BY r2.expireDate DESC
|
||||
LIMIT 1);";
|
||||
try
|
||||
{
|
||||
await using var con = new MySqlConnection(DBManagement.GetConnectionString(true));
|
||||
await con.OpenAsync();
|
||||
using var trans = await con.BeginTransactionAsync();
|
||||
using var multi = await con.QueryMultipleAsync(sql, new { size = Size, id = IdStorageServer }, trans);
|
||||
IList<dynamic> tokens = (await multi.ReadAsync()).AsList();
|
||||
IList<dynamic> rTokens = (await multi.ReadAsync()).AsList();
|
||||
using (var writer = new StreamWriter(Path.GetFullPath("Json/dataServer.json"), false))
|
||||
{
|
||||
await writer.WriteAsync(JsonConvert.SerializeObject(new
|
||||
{
|
||||
idRToken = "",
|
||||
rToken = "",
|
||||
cDate = "",
|
||||
eDate = "",
|
||||
token = "",
|
||||
idToken = ""
|
||||
}));
|
||||
}
|
||||
}
|
||||
catch (DbException ex)
|
||||
{
|
||||
|
||||
}
|
||||
return fMess;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
8
TWASys-App/Models/UserModel.cs
Normal file
8
TWASys-App/Models/UserModel.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace TWASys_App.Models
|
||||
{
|
||||
public class UserModel
|
||||
{
|
||||
public string Username { set; get; } = "";
|
||||
public string Password { set; get; } = "";
|
||||
}
|
||||
}
|
||||
@ -2,6 +2,7 @@
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using TWASys_App.Models.Login;
|
||||
|
||||
await WSNavigation.LoadJson();
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
@ -10,6 +11,7 @@ builder.Services.Configure<FormOptions>(o => {
|
||||
});
|
||||
builder.Services.AddControllers(options =>
|
||||
{
|
||||
options.Filters.Add(new LoginCheckFilter());
|
||||
options.Filters.Add<AsyncGateAttribute>();
|
||||
}).AddJsonOptions(options =>
|
||||
{
|
||||
|
||||
@ -38,7 +38,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\AppLibs\AppLibs\AppLibs.csproj" />
|
||||
<ProjectReference Include="..\AppLibs\AppLibs\AppLibs.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@ -6,113 +6,116 @@
|
||||
<div class="frm-login">
|
||||
<div class="ws-login">
|
||||
<div class="frm-header d-f f-c a-i-center">
|
||||
<a app-nav href="@Url.AbsoluteContent("~/")" class="c_logo d-f j-c-center">
|
||||
<a app-nav href="@Url.AbsoluteContent("~/")" class="c_logo d-f j-c-center mb-4">
|
||||
<img src="@Url.AbsoluteContent("~/images/logo/slogo.png")">
|
||||
|
||||
</a>
|
||||
<div class="AWizard tabcontents">
|
||||
<div class="tabcontent">
|
||||
|
||||
<div class="frm-header">
|
||||
<h2 class="title">Sign In</h2>
|
||||
<span class="d-f f-wrap desc a-i-center">Don’t have an account? <a href="javascript:void(0)" class="ml-2" id="navSignUp">Sign up</a></span>
|
||||
</div>
|
||||
<div class="frm-input mt-4">
|
||||
<label>Username</label>
|
||||
<div class="c-input">
|
||||
<span class="ico atg a-1x atg-user"></span>
|
||||
<input id="txtUser" type="text" class="input" placeholder="Your username" />
|
||||
<span class="line"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="frm-input mb-2">
|
||||
<label>Password</label>
|
||||
<div class="c-input">
|
||||
<span class="ico atg a-1x atg-user"></span>
|
||||
<input id="txtPass" type="password" class="input" placeholder="Your password" />
|
||||
<span class="line"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="c_validation" id="frm_login_summary">
|
||||
<p class="mess_error"></p>
|
||||
</div>
|
||||
<div class="frm-header d-f f-wrap j-c-between a-i-center">
|
||||
<a href="javascript:void(0)" id="forgetPass">Forget the password?</a>
|
||||
<button class="btn btn-primary btn-effect" id="SignIn">Sign in</button>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="tabcontent">
|
||||
<div class="frm-header">
|
||||
<h2 class="title">Don't You Remember Password?</h2>
|
||||
|
||||
</div>
|
||||
<div class="frm-input mt-4">
|
||||
<label>Địa chỉ email</label>
|
||||
<div class="c-input">
|
||||
<span class="ico atg a-1x atg-user"></span>
|
||||
<input type="text" class="input" placeholder="Nhập email" />
|
||||
<span class="line"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="frm-header d-f j-c-end">
|
||||
<button class="btn btn-secondary btnCB btn-effect mr-2">Quay lại</button>
|
||||
<button class="btn btn-primary btn-effect">Lấy lại mật khẩu</button>
|
||||
</div>
|
||||
<div class="frm-header d-f f-c">
|
||||
<span class="hint">
|
||||
Mật khẩu mới sẽ được gửi về hộp thư trong email của bạn.
|
||||
</span>
|
||||
<span class="hint mt-2">
|
||||
Sau khi được cấp mật khẩu mới vui lòng đổi lại mật khẩu trong trang thông tin tài khoản.
|
||||
</span>
|
||||
<span class="mt-2 hint">Trường hợp không nhận được email? <a href="javascript:void(0)" class="">Hãy nhắn tin cho chúng tôi!</a></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tabcontent">
|
||||
<div class="frm-header">
|
||||
<h2 class="title">Sign Up</h2>
|
||||
|
||||
</div>
|
||||
<div class="frm-input mt-4">
|
||||
<label>Địa chỉ email</label>
|
||||
<div class="c-input">
|
||||
<span class="ico atg a-1x atg-user"></span>
|
||||
<input type="text" class="input" placeholder="Nhập email" />
|
||||
<span class="line"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="frm-input">
|
||||
<label>Mật khẩu</label>
|
||||
<div class="c-input">
|
||||
<span class="ico atg a-1x atg-user"></span>
|
||||
<input type="password" class="input" placeholder="Nhập mật khẩu" />
|
||||
<span class="line"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="frm-input">
|
||||
<label>Nhập lại mật khẩu</label>
|
||||
<div class="c-input">
|
||||
<span class="ico atg a-1x atg-user"></span>
|
||||
<input type="password" class="input" placeholder="Nhập lại mật khẩu" />
|
||||
<span class="line"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="frm-input">
|
||||
<label>Họ & tên</label>
|
||||
<div class="c-input">
|
||||
<span class="ico atg a-1x atg-user"></span>
|
||||
<input type="text" class="input" placeholder="Nhập họ tên" />
|
||||
<span class="line"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="frm-header d-f j-c-end">
|
||||
<button class="btn btn-secondary btnCB btn-effect mr-2">Quay lại</button>
|
||||
<button class="btn btn-primary btn-effect">Đăng ký</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="AWizard tabcontents">
|
||||
<div class="tabcontent">
|
||||
|
||||
<div class="frm-header">
|
||||
<h2 class="title">Sign In</h2>
|
||||
<span class="d-f f-wrap desc">Bạn chưa có tài khoản? <a href="javascript:void(0)" class="ml-2" id="navSignUp">Đăng ký ngay</a></span>
|
||||
</div>
|
||||
<div class="frm-input mt-4">
|
||||
<label>Username</label>
|
||||
<div class="c-input">
|
||||
<span class="ico atg a-1x atg-user"></span>
|
||||
<input type="text" class="input" placeholder="Your username" />
|
||||
<span class="line"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="frm-input">
|
||||
<label>Password</label>
|
||||
<div class="c-input">
|
||||
<span class="ico atg a-1x atg-user"></span>
|
||||
<input type="password" class="input" placeholder="Your password" />
|
||||
<span class="line"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="frm-header d-f f-wrap j-c-between a-i-center">
|
||||
<a href="javascript:void(0)" id="forgetPass">Forget the password?</a>
|
||||
<button class="btn btn-primary btn-effect">Sign In</button>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="tabcontent">
|
||||
<div class="frm-header">
|
||||
<h2 class="title">Don't You Remember Password?</h2>
|
||||
|
||||
</div>
|
||||
<div class="frm-input mt-4">
|
||||
<label>Địa chỉ email</label>
|
||||
<div class="c-input">
|
||||
<span class="ico atg a-1x atg-user"></span>
|
||||
<input type="text" class="input" placeholder="Nhập email" />
|
||||
<span class="line"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="frm-header d-f j-c-end">
|
||||
<button class="btn btn-secondary btnCB btn-effect mr-2">Quay lại</button>
|
||||
<button class="btn btn-primary btn-effect">Lấy lại mật khẩu</button>
|
||||
</div>
|
||||
<div class="frm-header d-f f-c">
|
||||
<span class="hint">
|
||||
Mật khẩu mới sẽ được gửi về hộp thư trong email của bạn.
|
||||
</span>
|
||||
<span class="hint mt-2">
|
||||
Sau khi được cấp mật khẩu mới vui lòng đổi lại mật khẩu trong trang thông tin tài khoản.
|
||||
</span>
|
||||
<span class="mt-2 hint">Trường hợp không nhận được email? <a href="javascript:void(0)" class="">Hãy nhắn tin cho chúng tôi!</a></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tabcontent">
|
||||
<div class="frm-header">
|
||||
<h2 class="title">Sign Up</h2>
|
||||
|
||||
</div>
|
||||
<div class="frm-input mt-4">
|
||||
<label>Địa chỉ email</label>
|
||||
<div class="c-input">
|
||||
<span class="ico atg a-1x atg-user"></span>
|
||||
<input type="text" class="input" placeholder="Nhập email" />
|
||||
<span class="line"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="frm-input">
|
||||
<label>Mật khẩu</label>
|
||||
<div class="c-input">
|
||||
<span class="ico atg a-1x atg-user"></span>
|
||||
<input type="password" class="input" placeholder="Nhập mật khẩu" />
|
||||
<span class="line"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="frm-input">
|
||||
<label>Nhập lại mật khẩu</label>
|
||||
<div class="c-input">
|
||||
<span class="ico atg a-1x atg-user"></span>
|
||||
<input type="password" class="input" placeholder="Nhập lại mật khẩu" />
|
||||
<span class="line"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="frm-input">
|
||||
<label>Họ & tên</label>
|
||||
<div class="c-input">
|
||||
<span class="ico atg a-1x atg-user"></span>
|
||||
<input type="text" class="input" placeholder="Nhập họ tên" />
|
||||
<span class="line"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="frm-header d-f j-c-end">
|
||||
<button class="btn btn-secondary btnCB btn-effect mr-2">Quay lại</button>
|
||||
<button class="btn btn-primary btn-effect">Đăng ký</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -19,120 +19,122 @@
|
||||
<div class="cfull">
|
||||
<div class="r-n-g">
|
||||
<div class="c-12">
|
||||
<div class="card-body">
|
||||
<div class="d-f">
|
||||
<div class="card-body" data-dropdown>
|
||||
<div class="d-f dropdown aslidedown">
|
||||
<h4>Storage Initialization</h4>
|
||||
<div class="more"><span class="atg atg-more"></span></div>
|
||||
</div>
|
||||
<div class="d-f f-c form-group-con mb-2 ">
|
||||
<div class="form-group d-f f-c">
|
||||
<label>Total Size</label>
|
||||
<div class="input-custom d-f c-12 c-s-6">
|
||||
<button class="input-append left d-f a-i-center minus btn-effect waves-float">
|
||||
<span class="atg atg-minus"></span>
|
||||
</button>
|
||||
<div class="d-f w-100">
|
||||
<input id="totalSize" type="text" default-value="1" max-value="10000" min-value="1" step-value="1" placeholder="Dung Lượng Storage" validation-isEmpty />
|
||||
<span class="input-append right">Gb</span>
|
||||
<div class="sub-item">
|
||||
<div class="d-f f-c form-group-con mb-2 ">
|
||||
<div class="form-group d-f f-c">
|
||||
<label>Total Size</label>
|
||||
<div class="input-custom d-f c-12 c-s-6">
|
||||
<button class="input-append left d-f a-i-center minus btn-effect waves-float">
|
||||
<span class="atg atg-minus"></span>
|
||||
</button>
|
||||
<div class="d-f w-100">
|
||||
<input id="totalSize" type="text" default-value="1" max-value="10000" min-value="1" step-value="1" placeholder="Dung Lượng Storage" validation-isEmpty />
|
||||
<span class="input-append right">Gb</span>
|
||||
</div>
|
||||
<button class="input-append right d-f a-i-center plus btn-effect waves-float">
|
||||
<span class="atg atg-1x atg-plus"></span>
|
||||
</button>
|
||||
</div>
|
||||
<button class="input-append right d-f a-i-center plus btn-effect waves-float">
|
||||
<span class="atg atg-1x atg-plus"></span>
|
||||
</button>
|
||||
</div>
|
||||
<label>List Storage Server</label>
|
||||
<div class="input-custom amultitag d-f c-12 c-s-6" id="listStorage">
|
||||
<div class="d-f w-100 input-content"></div>
|
||||
<div class="input-append right d-f a-i-center plus btn-effect waves-float btn-Add">
|
||||
<span class="atg atg-plus"></span>
|
||||
<label>List Storage Server</label>
|
||||
<div class="input-custom amultitag d-f c-12 c-s-6" id="listStorage">
|
||||
<div class="d-f w-100 input-content"></div>
|
||||
<div class="input-append right d-f a-i-center plus btn-effect waves-float btn-Add">
|
||||
<span class="atg atg-plus"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-f f-c mt-1">
|
||||
<div class="invalid-feedback mess-empty"></div>
|
||||
</div>
|
||||
<div class="brn-group">
|
||||
<button id="btAdd" type="button" class="btn btn-effect btn-primary mt-2 waves-effect waves-float d-f a-i-center">
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-f f-c mt-1">
|
||||
<div class="invalid-feedback mess-empty"></div>
|
||||
</div>
|
||||
<div class="brn-group">
|
||||
<button id="btAdd" type="button" class="btn btn-effect btn-primary mt-2 waves-effect waves-float d-f a-i-center">
|
||||
Add
|
||||
</button>
|
||||
<button id="btLogin" type="button" class="btn btn-effect btn-primary mt-2 waves-effect waves-float d-f a-i-center">
|
||||
Login Microsoft 365
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="c-12">
|
||||
<div class="card-body">
|
||||
<div class="d-f">
|
||||
<div class="card-body" data-dropdown>
|
||||
<a class="d-f dropdown aslidedown">
|
||||
<h4>Storage Setting</h4>
|
||||
<div class="more"><span class="atg atg-more"></span></div>
|
||||
</div>
|
||||
<h5 class="mt-2 mb-2">Search Fillter</h5>
|
||||
<div class="d-f f-c form-group-con mb-2 ">
|
||||
<div class="form-group d-f f-c">
|
||||
<div class="input-group">
|
||||
<input id="inpKey" type="text" placeholder="Keyword" validation-isEmpty />
|
||||
</div>
|
||||
<div class="d-f f-c mt-1">
|
||||
<div class="invalid-feedback mess-empty"></div>
|
||||
</a>
|
||||
<div class="sub-item">
|
||||
<h5 class="mt-2 mb-2">Search Fillter</h5>
|
||||
<div class="d-f f-c form-group-con mb-2 ">
|
||||
<div class="form-group d-f f-c">
|
||||
<div class="input-group">
|
||||
<input id="inpKey" type="text" placeholder="Keyword" validation-isEmpty />
|
||||
</div>
|
||||
<div class="d-f f-c mt-1">
|
||||
<div class="invalid-feedback mess-empty"></div>
|
||||
|
||||
</div>
|
||||
<div class="brn-group">
|
||||
<button id="btSearch" type="button" class="btn btn-effect btn-primary mt-2 waves-effect waves-float d-f a-i-center">
|
||||
Search
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="atabs">
|
||||
<div class="tab-item">
|
||||
<a href="javascript:void(0)" class="item active">Searched Result</a>
|
||||
</div>
|
||||
<div class="tab-item">
|
||||
<a href="javascript:void(0)" class="item" disabled>Update Item</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-f f-c form-group-con">
|
||||
<div class="form-group tabcontents">
|
||||
<div class="tabcontent">
|
||||
<div class="c-table">
|
||||
</div>
|
||||
<div class="brn-group">
|
||||
<button id="btSearch" type="button" class="btn btn-effect btn-primary mt-2 waves-effect waves-float d-f a-i-center">
|
||||
Search
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tabcontent">
|
||||
<div class="d-f f-c form-group-con mb-2 ">
|
||||
<div class="form-group d-f f-c">
|
||||
<h5 class="mt-2 mb-2">Edit Storage Type</h5>
|
||||
<label for="inpType">Storage Type Name</label>
|
||||
<div class="input-group">
|
||||
<input id="inpEID" type="hidden" />
|
||||
<input id="inpEType" type="text" placeholder="Type Name" validation-isEmpty />
|
||||
</div>
|
||||
<div class="d-f f-c mt-1">
|
||||
<div class="invalid-feedback mess-empty"></div>
|
||||
</div>
|
||||
<div class="brn-group d-f mt-2">
|
||||
<button id="btUpdate" type="button" class="btn btn-effect btn-primary waves-effect waves-float d-f a-i-center">
|
||||
Update
|
||||
</button>
|
||||
<button id="btBack" type="button" class="btn btn-effect btn-primary ml-2 waves-effect waves-float d-f a-i-center">
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
<div class="atabs">
|
||||
<div class="tab-item">
|
||||
<a href="javascript:void(0)" class="item active">Searched Result</a>
|
||||
</div>
|
||||
<div class="tab-item">
|
||||
<a href="javascript:void(0)" class="item" disabled>Update Item</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-f f-c form-group-con">
|
||||
<div class="form-group tabcontents">
|
||||
<div class="tabcontent">
|
||||
<div class="c-table">
|
||||
</div>
|
||||
</div>
|
||||
<div class="tabcontent">
|
||||
<div class="d-f f-c form-group-con mb-2 ">
|
||||
<div class="form-group d-f f-c">
|
||||
<h5 class="mt-2 mb-2">Edit Storage Type</h5>
|
||||
<label for="inpType">Storage Type Name</label>
|
||||
<div class="input-group">
|
||||
<input id="inpEID" type="hidden" />
|
||||
<input id="inpEType" type="text" placeholder="Type Name" validation-isEmpty />
|
||||
</div>
|
||||
<div class="d-f f-c mt-1">
|
||||
<div class="invalid-feedback mess-empty"></div>
|
||||
</div>
|
||||
<div class="brn-group d-f mt-2">
|
||||
<button id="btUpdate" type="button" class="btn btn-effect btn-primary waves-effect waves-float d-f a-i-center">
|
||||
Update
|
||||
</button>
|
||||
<button id="btBack" type="button" class="btn btn-effect btn-primary ml-2 waves-effect waves-float d-f a-i-center">
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="c-12">
|
||||
<div class="card-body">
|
||||
<div class="d-f">
|
||||
<div class="card-body" data-dropdown>
|
||||
<div class="d-f dropdown aslidedown">
|
||||
<h4>Your Storage</h4>
|
||||
<div class="more"><span class="atg atg-more"></span></div>
|
||||
</div>
|
||||
<div class="sub-item">
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
user-select: none
|
||||
}
|
||||
|
||||
a {,
|
||||
a {
|
||||
text-decoration: none
|
||||
}
|
||||
|
||||
|
||||
@ -43,9 +43,9 @@
|
||||
.abs-table th {
|
||||
color: #fff;
|
||||
background-color: #36304a;
|
||||
padding: 20px 10px 20px;
|
||||
font-size: .9rem;
|
||||
font-weight: 500;
|
||||
padding: 18px 10px 18px;
|
||||
font-size: .82rem;
|
||||
font-weight: 600;
|
||||
text-transform: capitalize;
|
||||
letter-spacing: .5px
|
||||
}
|
||||
@ -64,7 +64,7 @@
|
||||
text-align: center;
|
||||
font-weight: 400;
|
||||
color: #808080;
|
||||
padding: 8px 15px
|
||||
padding: 15px
|
||||
}
|
||||
|
||||
.abs-container {
|
||||
|
||||
@ -53,7 +53,6 @@
|
||||
max-width: 100% !important
|
||||
}
|
||||
}
|
||||
|
||||
.ws-login {
|
||||
box-shadow: 0 2px 3px rgba(96, 96, 96, 0.1);
|
||||
background-color: #fff;
|
||||
@ -79,11 +78,12 @@
|
||||
padding-left: 25px;
|
||||
}
|
||||
|
||||
.ws-login .title, .ws-login .desc {
|
||||
.ws-login .desc{
|
||||
font-size: .92rem;
|
||||
}
|
||||
|
||||
.ws-login .hint {
|
||||
font-size: .82rem;
|
||||
font-size: .8rem;
|
||||
}
|
||||
|
||||
|
||||
@ -109,8 +109,8 @@
|
||||
margin-right: -15px;
|
||||
}
|
||||
|
||||
.frm-input, .frm-header {
|
||||
padding: 0 15px;
|
||||
.frm-input, .frm-header, .c_validation {
|
||||
padding: 0 5px;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
@ -162,4 +162,10 @@
|
||||
|
||||
.frm-input .c-input:not(.line) input:hover, .frm-input .c-input:not(.line) input:focus, .frm-input .con-aselect.active .aselect {
|
||||
border-color: var(--color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
.main-login a {
|
||||
color: #454545;
|
||||
font-size: .85rem;
|
||||
font-weight: 600
|
||||
}
|
||||
@ -28,6 +28,7 @@ html {
|
||||
font-weight: 500;
|
||||
}
|
||||
a{
|
||||
position: relative;
|
||||
text-decoration: none
|
||||
}
|
||||
|
||||
@ -73,8 +74,10 @@ body[page="10001"] #header {
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-weight: 600;
|
||||
color: #5e5873;
|
||||
margin-bottom: 5px
|
||||
color: #5e5873
|
||||
}
|
||||
h2{
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
h5 {
|
||||
@ -332,7 +335,7 @@ nav {
|
||||
cursor:pointer
|
||||
}
|
||||
|
||||
.active .more span{
|
||||
.active .more span {
|
||||
-webkit-transform: rotate(90deg);
|
||||
-moz-transform: rotate(90deg);
|
||||
-ms-transform: rotate(90deg);
|
||||
@ -340,7 +343,8 @@ nav {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
.more span {
|
||||
transition: all .3s ease-in;
|
||||
display: inline-block;
|
||||
transition: all .3s ease-in-out;
|
||||
transform: rotate(0)
|
||||
}
|
||||
.more {
|
||||
@ -464,6 +468,16 @@ nav {
|
||||
right: 0
|
||||
}
|
||||
|
||||
.card-body .dropdown{
|
||||
cursor: pointer
|
||||
}
|
||||
|
||||
.card-body .sub-item{
|
||||
box-shadow: none !important;
|
||||
position: relative !important
|
||||
}
|
||||
|
||||
|
||||
.card-body {
|
||||
border-radius: var(--border-radius);
|
||||
padding: 20px 20px;
|
||||
@ -793,6 +807,40 @@ nav {
|
||||
box-shadow: 0 3px 10px 0 rgb(34 41 47 / 10%);
|
||||
}
|
||||
|
||||
.amultitag .item{
|
||||
transition: all .3s ease-in-out;
|
||||
cursor: pointer;
|
||||
border-radius: var(--radius);
|
||||
margin: 5px;
|
||||
background: var(--color-primary);
|
||||
padding: 5px 10px;
|
||||
font-size: .8rem;
|
||||
color: #fff
|
||||
}
|
||||
.amultitag .item .con-ico {
|
||||
margin-left: 0;
|
||||
height: 20px;
|
||||
border-radius: 50%;
|
||||
color: #5e5873;
|
||||
visibility: hidden;
|
||||
width: 0;
|
||||
transition-delay: 0;
|
||||
transition: width .3s ease-in-out, visibility .3s ease-in-out;
|
||||
transition-delay: .3s;
|
||||
transition: background .3s ease-in-out, margin-left .3s ease-in-out
|
||||
}
|
||||
.amultitag .item:hover .con-ico {
|
||||
margin-left: 10px;
|
||||
background: #fff;
|
||||
visibility: visible;
|
||||
width: 20px
|
||||
}
|
||||
|
||||
.amultitag .item:hover .con-ico:hover{
|
||||
color:#fff;
|
||||
background: var(--secondary);
|
||||
}
|
||||
|
||||
.form-group input, .form-group .aselect, .form-group textarea {
|
||||
font-size: .85rem;
|
||||
width: 100%;
|
||||
@ -1210,17 +1258,17 @@ input[type=checkbox] {
|
||||
top: 50%;
|
||||
transform: translateY(-50%)
|
||||
}
|
||||
.mess-info{
|
||||
[class^=mess_] {
|
||||
font-size: .82rem;
|
||||
font-weight: 400;
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.mess-success {
|
||||
.mess_success {
|
||||
color: #28c76f;
|
||||
}
|
||||
|
||||
.mess-error {
|
||||
.mess_error {
|
||||
color: #ea5455;
|
||||
}
|
||||
|
||||
@ -1261,10 +1309,10 @@ input[type=checkbox] {
|
||||
background-color: #7367f0;
|
||||
box-shadow: 0 .125rem .25rem rgba(165, 163, 174, .3);
|
||||
}
|
||||
|
||||
|
||||
.animationSlide {
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.animationSlide .slideContent {
|
||||
@ -1273,11 +1321,16 @@ input[type=checkbox] {
|
||||
}
|
||||
|
||||
.animationSlide .tabcontent.show {
|
||||
visibility: visible;
|
||||
height: auto;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.animationSlide .tabcontent {
|
||||
opacity: 0;
|
||||
transition: .3s all ease-in-out
|
||||
visibility:hidden;
|
||||
height: 0;
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
.animationFade .tabcontent {
|
||||
@ -1302,4 +1355,10 @@ input[type=checkbox] {
|
||||
.awStorageConnector .tabcontent .form-group{
|
||||
padding: 0;
|
||||
}
|
||||
/*******************End Page**********************/
|
||||
/*******************End Page**********************/
|
||||
|
||||
|
||||
/*********Login Form**********/
|
||||
.c_validation{
|
||||
margin-bottom: 15px !important
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import AWizard from "/js/libs/js-AWizard.js";
|
||||
import AButton from "/js/libs/js-AButton.js";
|
||||
|
||||
window.L10001 = function () {
|
||||
Waves.attach('.btn-effect', ['waves-float']);
|
||||
@ -18,6 +19,49 @@ window.L10001 = function () {
|
||||
navSignUp.addEventListener("click", (e) => {
|
||||
wrd1.nextPage(2);
|
||||
});
|
||||
|
||||
window.requestTimeout(() => {
|
||||
const v = document.querySelector(".c-login");
|
||||
let top = (v.parentElement.clientHeight / 2) - (v.clientHeight / 2);
|
||||
if (v.clientHeight <= window.innerHeight) {
|
||||
top = top - (window.innerHeight - v.clientHeight) / 2
|
||||
} else {
|
||||
top = top - 40;
|
||||
}
|
||||
|
||||
if (window.getOS() == "iOS") {
|
||||
} else {
|
||||
window.smScroll.scrollTop = top;
|
||||
}
|
||||
}, 500);
|
||||
|
||||
let btn = new AButton(document.getElementById("SignIn"));
|
||||
btn.on("click_SignIn", (el) => {
|
||||
btn.AddLoading(el);
|
||||
document.querySelector("#frm_login_summary .mess_error").innerHTML = "";
|
||||
let promise = new Promise(async function (resolve, reject) {
|
||||
const fd = new FormData();
|
||||
fd.append("username", document.getElementById("txtUser").value);
|
||||
fd.append("password", document.getElementById("txtPass").value)
|
||||
const response = await fetch(`/Login/SignIn`, {
|
||||
method: 'POST',
|
||||
body: fd
|
||||
});
|
||||
const data = await response.json();
|
||||
if (data) {
|
||||
switch (data.Status) {
|
||||
case 0:
|
||||
document.querySelector("#frm_login_summary .mess_error").innerHTML = data.Message;
|
||||
break;
|
||||
case 1:
|
||||
window.app.initNavApp("/");
|
||||
break;
|
||||
}
|
||||
btn.RemoveLoading(el);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
function ComeBack(e, wrd) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -14,7 +14,6 @@ class AsyncLayout extends ALayout {
|
||||
super.dispose();
|
||||
}
|
||||
renderMenu() {
|
||||
console.log("ÁDASD");
|
||||
this.isLoaded = true;
|
||||
var asyncStyleSheets = [
|
||||
'https://fonts.googleapis.com/css2?family=Quicksand:wght@300;400;500;600;700&display=swap',
|
||||
@ -46,9 +45,6 @@ class AsyncLayout extends ALayout {
|
||||
window.app.initScrollBar();
|
||||
window.Scrollbar.init(document.querySelector('.mini-scrollbar'), sOption);
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -22,16 +22,9 @@ class LoginLayout extends ALayout {
|
||||
window.app.loadCSS(asyncStyleSheets);
|
||||
window.app.initNavs("Login");
|
||||
|
||||
var sOption = {
|
||||
damping: (window.getOS() == "Android") ? .06 : .04,
|
||||
thumbMinSize: 25,
|
||||
renderByPixel: true,
|
||||
alwaysShowTracks: true,
|
||||
continuousScrolling: true
|
||||
};
|
||||
|
||||
window.Scrollbar.use(window.OverscrollPlugin);
|
||||
window.app.initScrollBar();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -44,12 +44,16 @@
|
||||
}).bind(this);
|
||||
break;
|
||||
case "Slide":
|
||||
var slideC = document.createElement("div");
|
||||
slideC.classList.add("slideContent");
|
||||
while (this.params.parent.childNodes.length > 0) {
|
||||
slideC.appendChild(this.params.parent.childNodes[0]);
|
||||
var slideC = this.params.parent.querySelector(".slideContent");
|
||||
if (slideC == null) {
|
||||
slideC = document.createElement("div");
|
||||
slideC.classList.add("slideContent");
|
||||
while (this.params.parent.childNodes.length > 0) {
|
||||
slideC.appendChild(this.params.parent.childNodes[0]);
|
||||
}
|
||||
this.params.parent.appendChild(slideC);
|
||||
}
|
||||
this.params.parent.appendChild(slideC);
|
||||
|
||||
|
||||
slideC.querySelectorAll(".tabcontent").forEach((el) => {
|
||||
let style = this.params.parent.currentStyle || window.getComputedStyle(this.params.parent);
|
||||
|
||||
@ -51,7 +51,6 @@ export default class Dropdown extends window.AObject {
|
||||
if (this.isLock) {
|
||||
return;
|
||||
}
|
||||
console.log("Asdasd");
|
||||
var t1 = e.currentTarget;
|
||||
var p = t1.closest('[data-dropdown]');
|
||||
var p1 = e.target.closest(".noopen");
|
||||
|
||||
@ -10,10 +10,10 @@ export default class AMenu extends window.AObject {
|
||||
this.navD = document.querySelector(nav);
|
||||
this.transition = new ATransitionEffect();
|
||||
this.overlay = new AOverlay(document.body);
|
||||
|
||||
|
||||
this.isMDiffD = isMDiffD;
|
||||
this.changeActive();
|
||||
|
||||
|
||||
if (btnMs != null) {
|
||||
if (!(Array.isArray(btnMs) || btnMs instanceof NodeList || btnMs instanceof HTMLCollection)) {
|
||||
const tmp = [];
|
||||
@ -21,14 +21,14 @@ export default class AMenu extends window.AObject {
|
||||
btnMs = tmp;
|
||||
}
|
||||
btnMs.forEach((el => {
|
||||
|
||||
|
||||
var f = function (e) {
|
||||
this.mobileMenu.call(this, e, el);
|
||||
}.bind(this);
|
||||
el.addEventListener(this.eventName, f, false);
|
||||
this.addSystemEvent(this.eventName, el, f, "icomenu");
|
||||
this.listIco.push(el);
|
||||
|
||||
|
||||
}).bind(this));
|
||||
this.overlay.createOverlay();
|
||||
this.overlay.setIndex(2000);
|
||||
@ -54,7 +54,7 @@ export default class AMenu extends window.AObject {
|
||||
this.initNav(this.navM, "M");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
initNav(ele, type = "D") {
|
||||
let arr = ele.querySelectorAll(".nav-i.has-sub .nav-link, .navmain > .nav-i:not(.has-sub) a");
|
||||
Array.from(arr).forEach(el => {
|
||||
@ -81,10 +81,10 @@ export default class AMenu extends window.AObject {
|
||||
}
|
||||
updateIdPage() {
|
||||
this.idPage = document.head.querySelector("meta[name=idPage]").content;
|
||||
|
||||
|
||||
this.navActiveD = this.navD.querySelector("a[nav-id='" + this.idPage + "']");
|
||||
if (this.isMDiffD) {
|
||||
this.navActiveM = this.navM.querySelector("a[nav-id='" + this.idPage + "']");
|
||||
this.navActiveM = this.navM.querySelector("a[nav-id='" + this.idPage + "']");
|
||||
}
|
||||
window.removeStopCollapsed();
|
||||
}
|
||||
@ -140,7 +140,7 @@ export default class AMenu extends window.AObject {
|
||||
}
|
||||
}).bind(this));
|
||||
}).bind(this), 100);
|
||||
|
||||
|
||||
}
|
||||
closeExpandMenu() {
|
||||
Array.from(this.navM.querySelectorAll(".nav-i.has-sub")).forEach(el => {
|
||||
|
||||
@ -52,7 +52,9 @@ export default class AModal extends window.AObject {
|
||||
showModal() {
|
||||
this.overlay.showOverlay();
|
||||
}
|
||||
|
||||
removeModal() {
|
||||
this.overlay.removeOverlay();
|
||||
}
|
||||
}
|
||||
|
||||
class AModalOK {
|
||||
|
||||
@ -3,8 +3,8 @@ export default class AMultiTag extends window.AObject {
|
||||
super();
|
||||
this.parent = ele;
|
||||
this.cItems = ele.querySelector(".input-content");
|
||||
this.itemEles = [];
|
||||
this.itemDatas = [];
|
||||
this.itemEles = new Map();
|
||||
this.itemDatas = new Map();
|
||||
this.btnAdd = ele.querySelector(".btn-Add");
|
||||
this.btnAdd.addEventListener("click", ((e) => {
|
||||
this.parent.classList.add("active");
|
||||
@ -16,6 +16,11 @@ export default class AMultiTag extends window.AObject {
|
||||
}
|
||||
initGlobalVar() {
|
||||
var f = function (ev) {
|
||||
const close = ev.target.closest(".con-ico");
|
||||
if (close) {
|
||||
const t = close.closest(".item[data-id]");
|
||||
if (t) this.removeItem(1 * t.getAttribute("data-id"));
|
||||
}
|
||||
if (ev.target.closest(".amultitag") || ev.target.closest(".c-aoverlay")) {
|
||||
return;
|
||||
} else {
|
||||
@ -26,22 +31,32 @@ export default class AMultiTag extends window.AObject {
|
||||
window.AMultiTag = true;
|
||||
}
|
||||
addItem(id, name, obj, action = null) {
|
||||
var ele = this.addItem(id, name, action);
|
||||
this.itemEles.push(ele);
|
||||
this.itemDatas.push(obj);
|
||||
var ele = this.createItem(id, name, action);
|
||||
this.itemEles.set(id, ele);
|
||||
this.itemDatas.set(id, obj);
|
||||
this.cItems.appendChild(ele);
|
||||
}
|
||||
removeItem(id) {
|
||||
const t = this.itemEles.get(id);
|
||||
this.itemDatas.delete(id);
|
||||
this.itemEles.delete(id);
|
||||
t.remove();
|
||||
}
|
||||
createItem(id, name, action) {
|
||||
var p = document.createElement("div");
|
||||
p.setAttribute("data-id", id);
|
||||
p.classList.add("item");
|
||||
p.classList.add("item", "d-f", "a-i-center");
|
||||
var label = document.createElement("span");
|
||||
label.innerHTML = name;
|
||||
label.classList.add("name");
|
||||
if (action != null) {
|
||||
p.appendChild(action);
|
||||
}
|
||||
let close = document.createElement("div");
|
||||
close.classList.add("con-ico", "d-f", "a-i-center", "j-c-center");
|
||||
p.appendChild(label);
|
||||
close.innerHTML = `<span class="atg a-1x atg-x"></span>`;
|
||||
p.appendChild(close);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
@ -182,6 +182,7 @@ class ASelectEle extends window.AObject {
|
||||
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);
|
||||
@ -398,7 +399,6 @@ class ASelectEle extends window.AObject {
|
||||
}
|
||||
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,
|
||||
|
||||
69
TWASys-App/wwwroot/js/libs/js-ASlideDown.js
Normal file
69
TWASys-App/wwwroot/js/libs/js-ASlideDown.js
Normal file
@ -0,0 +1,69 @@
|
||||
import ATransitionEffect from '/js/libs/js-ATransitionEffect.js'
|
||||
|
||||
export default class ASlideDown extends window.AObject {
|
||||
constructor(el) {
|
||||
super();
|
||||
this._eleM = [];
|
||||
if (el instanceof NodeList) {
|
||||
Array.from(el).forEach((e) => {
|
||||
this._eleM.push(new ASlideDownEle(e))
|
||||
});
|
||||
} else {
|
||||
this._eleM.push(new ASlideDownEle(el));
|
||||
}
|
||||
}
|
||||
get(i) {
|
||||
return this._eleM[i];
|
||||
}
|
||||
}
|
||||
|
||||
class ASlideDownEle extends window.AObject {
|
||||
constructor(ele) {
|
||||
super();
|
||||
this.transition = new ATransitionEffect();
|
||||
this._ele = ele;
|
||||
this._pCon = ele.closest('[data-dropdown]');
|
||||
this._subI = this._pCon.querySelector(".sub-item");
|
||||
var f = function (ev) {
|
||||
if (window.isValidPointerClick(ev)) return;
|
||||
this.onClick.call(this, ev);
|
||||
}.bind(this);
|
||||
this.addSystemEvent(this.eventName, this._ele, f);
|
||||
}
|
||||
enable() {
|
||||
this._ele.classList.remove("disabled");
|
||||
}
|
||||
disable() {
|
||||
this._ele.classList.add("disabled");
|
||||
}
|
||||
enable_Open() {
|
||||
this.enable();
|
||||
this.open();
|
||||
}
|
||||
disable_Close() {
|
||||
this.disable();
|
||||
this.close();
|
||||
}
|
||||
open() {
|
||||
if (this._ele.classList.contains("disabled")) {
|
||||
return;
|
||||
}
|
||||
this._pCon.classList.add("active");
|
||||
this.transition.expandEffect(this._subI, function () {
|
||||
this.trigger("opened");
|
||||
}.bind(this));
|
||||
}
|
||||
close() {
|
||||
this._pCon.classList.remove("active");
|
||||
this.transition.collapsedEffect(this._subI, function () {
|
||||
this.trigger("closed");
|
||||
}.bind(this));
|
||||
}
|
||||
onClick(e) {
|
||||
if (this._pCon.classList.contains("active")) {
|
||||
this.close();
|
||||
} else {
|
||||
this.open();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -33,7 +33,14 @@ export default class AWizard extends ATab {
|
||||
Cancel
|
||||
</button>
|
||||
</div>`;
|
||||
|
||||
|
||||
const ro = new ResizeObserver((entries => {
|
||||
for (const e of entries) {
|
||||
const { width, height } = e.contentRect;
|
||||
this.aAnimation.setType(this.typeAnimation, { "parent": this.tabContents });
|
||||
}
|
||||
}).bind(this));
|
||||
ro.observe(this.tabContents);
|
||||
}
|
||||
showPage(i) {
|
||||
this.cPage = i;
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
this.pElement = e;
|
||||
this.Headers = [];
|
||||
this.lSysRows = [];
|
||||
this.labelID = "";
|
||||
this.InitStructure();
|
||||
this.InitCss();
|
||||
this.SetIdCheckBox();
|
||||
@ -18,7 +19,8 @@
|
||||
}
|
||||
}
|
||||
SetScrollBarY(height) {
|
||||
this.absContainerRows.style.height = height + "px";
|
||||
this.absContainerRows.style.height = "auto";
|
||||
this.absContainerRows.style.maxHeight = height + "px";
|
||||
}
|
||||
AddHeader(name, width, minWidth, id = "", rowTemp = null) {
|
||||
var d = document.createElement("th");
|
||||
@ -184,10 +186,15 @@
|
||||
this.data.forEach((e, i) => {
|
||||
var r = document.createElement("tr");
|
||||
r.setAttribute("data-id", i);
|
||||
this.Headers.forEach((o) => {
|
||||
this.Headers.forEach((o, j) => {
|
||||
|
||||
var td = document.createElement("td");
|
||||
if (o.rowTemp != null) {
|
||||
td.appendChild(o.rowTemp(i, e));
|
||||
const rT = o.rowTemp(i, e);
|
||||
if (this.isCheckBox && j < 1) {
|
||||
rT.setAttribute("id", (this.labelID.length >0)?e[this.labelID]:"");
|
||||
}
|
||||
td.appendChild(rT);
|
||||
} else {
|
||||
td.innerHTML = e[o.id];
|
||||
}
|
||||
|
||||
@ -104,14 +104,14 @@ window.getOS = function () {
|
||||
return os;
|
||||
}
|
||||
|
||||
window.GetAbsoluteURL = function(relativeURL) {
|
||||
window.GetAbsoluteURL = function (relativeURL) {
|
||||
if (relativeURL.startsWith(window.location.origin)) {
|
||||
return relativeURL;
|
||||
}
|
||||
return window.location.origin + relativeURL;
|
||||
}
|
||||
|
||||
window.getPathFromUrl = function(url) {
|
||||
window.getPathFromUrl = function (url) {
|
||||
const parsed = new URL(url);
|
||||
return parsed.pathname + parsed.search + parsed.hash;
|
||||
}
|
||||
@ -377,9 +377,9 @@ window.AObject = class {
|
||||
const eventMap = this.systemEvents.get(element);
|
||||
if (eventMap) {
|
||||
const data = eventMap.get(eventName);
|
||||
|
||||
|
||||
if (data && typeof data.callback === 'function') {
|
||||
element.removeEventListener(eventName , data.callback, false);
|
||||
element.removeEventListener(eventName, data.callback, false);
|
||||
eventMap.delete(eventName);
|
||||
// Nếu element không còn event nào, xóa khỏi systemEvents
|
||||
if (eventMap.size === 0) {
|
||||
@ -387,7 +387,7 @@ window.AObject = class {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
this.parentEventMap.delete(parent);
|
||||
}
|
||||
@ -406,7 +406,7 @@ window.AObject = class {
|
||||
}
|
||||
addCustomEvent(id, element, groups = null) {
|
||||
if (!this.customEvents.has(id)) {
|
||||
this.customEvents.set(id, { "ele":element, "groups":groups });
|
||||
this.customEvents.set(id, { "ele": element, "groups": groups });
|
||||
}
|
||||
if (groups) {
|
||||
if (!this.parentEventMap.has("Custom" + parent)) {
|
||||
@ -429,6 +429,7 @@ window.AObject = class {
|
||||
}
|
||||
this.parentEventMap.get(parent).add({ element, eventName });
|
||||
}
|
||||
|
||||
}
|
||||
removeAllChildNodes(parent) {
|
||||
while (parent.firstChild) {
|
||||
@ -541,12 +542,11 @@ class AApp extends window.AObject {
|
||||
this.metaPage = document.head.querySelector("meta[name=idPage]");
|
||||
this.pageName = this.metaPage.getAttribute("pageName");
|
||||
this.lName = this.metaPage.getAttribute("layName");
|
||||
console.log(this.lName);
|
||||
var tmp = document.querySelector(container);
|
||||
this.mainApp = tmp.querySelector("[main-content]") ? tmp.querySelector("[main-content]") : tmp;
|
||||
var f = function (ev) {
|
||||
if (ev.state) {
|
||||
this.cachePage.get(ev.state.url, ((result) => {
|
||||
this.cachePage.get(ev.state.url, ((result) => {
|
||||
if (result == null) {
|
||||
|
||||
} else {
|
||||
@ -655,7 +655,7 @@ class AApp extends window.AObject {
|
||||
this.addSystemEvent("click", el, f1, groups)
|
||||
const f2 = (function (ev) {
|
||||
if (window.isValidPointerClick(ev)) return;
|
||||
|
||||
|
||||
this.initNavApp(ev.currentTarget.getAttribute("href"), ev.currentTarget.hasAttribute("isflexpage"));
|
||||
}).bind(this);
|
||||
this.addSystemEvent(this.eventName, el, f2, groups);
|
||||
@ -689,8 +689,7 @@ class AApp extends window.AObject {
|
||||
doc: doc,
|
||||
dynamicF: a.dynamicF
|
||||
};
|
||||
|
||||
this.setContentPage(obj, url);
|
||||
this.setContentPage(obj, url);
|
||||
} else {
|
||||
this.getPage(url, result)
|
||||
}
|
||||
@ -699,17 +698,6 @@ class AApp extends window.AObject {
|
||||
this.getPage(url);
|
||||
}
|
||||
}).bind(this));
|
||||
//if (flex) {
|
||||
|
||||
//} else {
|
||||
// this.cachePage.get(url, ((result) => {
|
||||
// if (result) {
|
||||
// // Set content page từ cache
|
||||
// } else {
|
||||
// this.getPage(url); // Load mới nếu chưa có trong cache
|
||||
// }
|
||||
// }).bind(this));
|
||||
//}
|
||||
}
|
||||
loadContentPage(content) {
|
||||
const tpl = document.createElement('template');
|
||||
@ -723,12 +711,10 @@ class AApp extends window.AObject {
|
||||
document.title = page.title + " - " + this.pageName;
|
||||
var meta = document.head.querySelector("meta[name=idPage]");
|
||||
document.body.setAttribute("page", page.idPage);
|
||||
|
||||
meta.content = page.idPage;
|
||||
this.lName = page.lName;
|
||||
meta.setAttribute("layName", page.lName);
|
||||
meta.setAttribute("layName", page.lName);
|
||||
this.loadContentPage(page.html);
|
||||
window.history.pushState({"url":url}, page.title, url);
|
||||
window.history.pushState({ "url": url }, page.title, url);
|
||||
}
|
||||
setContentPage(page, url) {
|
||||
this.contentPage(page, url);
|
||||
@ -778,7 +764,6 @@ class AApp extends window.AObject {
|
||||
loadedPage() {
|
||||
this.metaPage = document.head.querySelector("meta[name=idPage]");
|
||||
if (this.metaPage != null && this.isLoadedLayout) {
|
||||
console.log(window.location.href);
|
||||
this.cachePage.searchFlexPage(window.getPathFromUrl(window.location.href), ((tmp) => {
|
||||
tmp = tmp.layout.info;
|
||||
if (tmp != null && tmp.dynamicF != null) {
|
||||
@ -790,7 +775,7 @@ class AApp extends window.AObject {
|
||||
this.initNavs(this.metaPage.content);
|
||||
this.trigger("pageLoaded", null);
|
||||
}).bind(this));
|
||||
|
||||
|
||||
} else {
|
||||
window.requestTimeout(this.loadedPage.bind(this), 10, window.registerCancel);
|
||||
}
|
||||
@ -803,9 +788,9 @@ class AApp extends window.AObject {
|
||||
console.log("connect new Layout");
|
||||
this.loadLayout(); // Load mới nếu chưa có trong cache
|
||||
}
|
||||
|
||||
|
||||
}).bind(this), "layout");
|
||||
|
||||
|
||||
}
|
||||
loadLayout() {
|
||||
(function () {
|
||||
@ -825,10 +810,9 @@ class AApp extends window.AObject {
|
||||
}).bind(this)();
|
||||
}
|
||||
loadedLayout() {
|
||||
console.log(this.lName);
|
||||
if (this.lName !== "None") {
|
||||
const l = window.ALayout.get(this.lName);
|
||||
if (!l.isLoaded) {
|
||||
if (!l.isLoaded) {
|
||||
l.renderMenu();
|
||||
this.isLoadedLayout = true;
|
||||
this.trigger("layoutLoaded", null);
|
||||
@ -928,7 +912,7 @@ class CacheManager {
|
||||
|
||||
// Lấy thông tin trang hoặc layout
|
||||
|
||||
|
||||
|
||||
// Lấy dữ liệu từ cache (localStorage hoặc IndexedDB nếu cần)
|
||||
get(id, callback, type = "cahce") {
|
||||
this._onReady(() => {
|
||||
@ -986,7 +970,7 @@ class CacheManager {
|
||||
this.countFP++;
|
||||
}
|
||||
this.storage.set("treePage", this.flexPages.toJSON(), function () { });
|
||||
} else {
|
||||
} else {
|
||||
const layout = {
|
||||
Content: obj.Content,
|
||||
Scripts: obj.Scripts
|
||||
@ -1054,7 +1038,7 @@ class CacheStorage {
|
||||
del.onblocked = () => {
|
||||
console.warn("deleteDatabase blocked (tab khác đang giữ kết nối)");
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
_flushQueue() {
|
||||
while (this.queue.length) {
|
||||
@ -1104,7 +1088,7 @@ class CacheStorage {
|
||||
}
|
||||
});
|
||||
}
|
||||
set(key, data, callback = () => { }, type="cache") {
|
||||
set(key, data, callback = () => { }, type = "cache") {
|
||||
this._onReady(() => {
|
||||
if (this.db) {
|
||||
let tx, store, req;
|
||||
@ -1117,7 +1101,7 @@ class CacheStorage {
|
||||
store = tx.objectStore("cache");
|
||||
store.put({ key: this._key(key), value: data, ts: Date.now() });
|
||||
}
|
||||
|
||||
|
||||
tx.oncomplete = () => callback(null);
|
||||
tx.onerror = (e) => callback(e);
|
||||
} else {
|
||||
@ -1126,7 +1110,7 @@ class CacheStorage {
|
||||
localStorage.setItem(this._key(key), JSON.stringify({ data, ts: Date.now() }));
|
||||
callback(null);
|
||||
} catch (e) {
|
||||
|
||||
|
||||
callback(e);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user