1.0.2
Correct ts
This commit is contained in:
parent
b32b4b9198
commit
1bd84ca8d2
@ -4,20 +4,47 @@ using AppWeb.Models;
|
||||
|
||||
namespace AppWeb.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// Ãëàâíûé êîíòðîëëåð
|
||||
/// </summary>
|
||||
public class HomeController : Controller
|
||||
{
|
||||
private readonly ILogger<HomeController> _logger;
|
||||
|
||||
/// <summary>
|
||||
/// Êîíñòðóêòîð
|
||||
/// </summary>
|
||||
/// <param name="logger">Ëîãèðîâàíèå MVC</param>
|
||||
public HomeController(ILogger<HomeController> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ãëàâíàÿ
|
||||
/// </summary>
|
||||
[HttpGet]
|
||||
[Route("/")]
|
||||
public IActionResult Index()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Êîíòàêòû
|
||||
/// </summary>
|
||||
[HttpGet]
|
||||
[Route("/contacts")]
|
||||
public IActionResult Contacts()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Îøèáêà
|
||||
/// </summary>
|
||||
[HttpGet]
|
||||
[Route("/error")]
|
||||
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
|
||||
public IActionResult Error()
|
||||
{
|
||||
|
@ -20,3 +20,125 @@ html {
|
||||
body {
|
||||
margin-bottom: 60px;
|
||||
}
|
||||
|
||||
/*
|
||||
**************************
|
||||
START ALERT
|
||||
**************************
|
||||
*/
|
||||
|
||||
/* Основные стили для контейнера уведомлений */
|
||||
#notification-container {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
left: 20px;
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.error_alert_animate {
|
||||
border: 1px solid #AC0B00;
|
||||
}
|
||||
|
||||
.ok_alert_animate {
|
||||
border: 1px solid #007126;
|
||||
}
|
||||
|
||||
.warning_alert_animate {
|
||||
border: 1px solid #A33E00;
|
||||
}
|
||||
|
||||
/* Стили для уведомлений */
|
||||
.notification {
|
||||
background-color: #333;
|
||||
color: white;
|
||||
border-radius: 8px;
|
||||
padding: 10px 20px;
|
||||
margin-bottom: 10px;
|
||||
font-size: 16px;
|
||||
max-width: 300px;
|
||||
opacity: 1;
|
||||
animation: slideUpAndFade 5s ease-in-out forwards;
|
||||
}
|
||||
|
||||
/* Анимация для подъема уведомления вверх и его исчезновения */
|
||||
@keyframes slideUpAndFade {
|
||||
0% {
|
||||
transform: translateY(0);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: translateY(-50%); /* Поднимаем уведомление до середины экрана */
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translateY(-100%); /* Двигаем уведомление еще выше */
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
**************************
|
||||
END ALERT
|
||||
**************************
|
||||
*/
|
||||
|
||||
/*
|
||||
**************************
|
||||
START ANIMS
|
||||
**************************
|
||||
*/
|
||||
|
||||
|
||||
.puff-in-center {
|
||||
-webkit-animation: puff-in-center 0.1s cubic-bezier(0.470, 0.000, 0.745, 0.715) both;
|
||||
animation: puff-in-center 0.1s cubic-bezier(0.470, 0.000, 0.745, 0.715) both;
|
||||
}
|
||||
|
||||
/**
|
||||
* ----------------------------------------
|
||||
* animation puff-in-center
|
||||
* ----------------------------------------
|
||||
*/
|
||||
@-webkit-keyframes puff-in-center {
|
||||
0% {
|
||||
-webkit-transform: scale(2);
|
||||
transform: scale(2);
|
||||
-webkit-filter: blur(4px);
|
||||
filter: blur(4px);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
100% {
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
-webkit-filter: blur(0px);
|
||||
filter: blur(0px);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes puff-in-center {
|
||||
0% {
|
||||
-webkit-transform: scale(2);
|
||||
transform: scale(2);
|
||||
-webkit-filter: blur(4px);
|
||||
filter: blur(4px);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
100% {
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
-webkit-filter: blur(0px);
|
||||
filter: blur(0px);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
**************************
|
||||
END ANIMS
|
||||
**************************
|
||||
*/
|
@ -0,0 +1,2 @@
|
||||
export {};
|
||||
//# sourceMappingURL=BaseEvents.js.map
|
@ -0,0 +1 @@
|
||||
{"version":3,"file":"BaseEvents.js","sourceRoot":"","sources":["../../../TypeScripts/Base/Components/BaseEvents.ts"],"names":[],"mappings":""}
|
@ -0,0 +1,33 @@
|
||||
export class Alerts {
|
||||
AlertShow(notification) {
|
||||
const container = document.getElementById('notification-container');
|
||||
if (!container)
|
||||
return;
|
||||
const newNotification = document.createElement('div');
|
||||
newNotification.classList.add('notification');
|
||||
switch (notification.type) {
|
||||
case TypeAlert.Error:
|
||||
newNotification.classList.add('error_alert_animate');
|
||||
break;
|
||||
case TypeAlert.Ok:
|
||||
newNotification.classList.add('ok_alert_animate');
|
||||
break;
|
||||
case TypeAlert.Warning:
|
||||
newNotification.classList.add('warning_alert_animate');
|
||||
break;
|
||||
}
|
||||
newNotification.textContent = notification.text;
|
||||
container.appendChild(newNotification);
|
||||
newNotification.classList.add('puff-in-center');
|
||||
setTimeout(() => {
|
||||
newNotification.remove();
|
||||
}, notification.duration * 1000);
|
||||
}
|
||||
}
|
||||
export var TypeAlert;
|
||||
(function (TypeAlert) {
|
||||
TypeAlert["Error"] = "error";
|
||||
TypeAlert["Warning"] = "warning";
|
||||
TypeAlert["Ok"] = "ok";
|
||||
})(TypeAlert || (TypeAlert = {}));
|
||||
//# sourceMappingURL=Alerts.js.map
|
@ -0,0 +1 @@
|
||||
{"version":3,"file":"Alerts.js","sourceRoot":"","sources":["../../../../TypeScripts/Base/Services/Alerts/Alerts.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,MAAM;IAIR,SAAS,CAAC,YAA+B;QAC5C,MAAM,SAAS,GAAG,QAAQ,CAAC,cAAc,CAAC,wBAAwB,CAAC,CAAC;QACpE,IAAI,CAAC,SAAS;YAAE,OAAO;QAGvB,MAAM,eAAe,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QACtD,eAAe,CAAC,SAAS,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAE9C,QAAQ,YAAY,CAAC,IAAI,EAAE,CAAC;YACxB,KAAK,SAAS,CAAC,KAAK;gBAChB,eAAe,CAAC,SAAS,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;gBACrD,MAAM;YACV,KAAK,SAAS,CAAC,EAAE;gBACb,eAAe,CAAC,SAAS,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;gBAClD,MAAM;YACV,KAAK,SAAS,CAAC,OAAO;gBAClB,eAAe,CAAC,SAAS,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;gBACvD,MAAM;QACd,CAAC;QAED,eAAe,CAAC,WAAW,GAAG,YAAY,CAAC,IAAI,CAAC;QAGhD,SAAS,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC;QACvC,eAAe,CAAC,SAAS,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QAGhD,UAAU,CAAC,GAAG,EAAE;YACZ,eAAe,CAAC,MAAM,EAAE,CAAC;QAC7B,CAAC,EAAE,YAAY,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IACrC,CAAC;CACJ;AAiBD,MAAM,CAAN,IAAY,SAIX;AAJD,WAAY,SAAS;IACjB,4BAAe,CAAA;IACf,gCAAmB,CAAA;IACnB,sBAAS,CAAA;AACb,CAAC,EAJW,SAAS,KAAT,SAAS,QAIpB"}
|
26
APP_WEB/ScriptsAndCss/JsScripts/Base/Services/Cookies.js
Normal file
26
APP_WEB/ScriptsAndCss/JsScripts/Base/Services/Cookies.js
Normal file
@ -0,0 +1,26 @@
|
||||
export class Cookies {
|
||||
getCookie(cookieName) {
|
||||
const name = cookieName + "=";
|
||||
const decodedCookie = decodeURIComponent(document.cookie);
|
||||
const ca = decodedCookie.split(";");
|
||||
for (let i = 0; i < ca.length; i++) {
|
||||
let c = ca[i];
|
||||
while (c.charAt(0) === " ") {
|
||||
c = c.substring(1);
|
||||
}
|
||||
if (c.indexOf(name) === 0) {
|
||||
return c.substring(name.length, c.length);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
setCookie(name, value, days) {
|
||||
const date = new Date();
|
||||
date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
|
||||
document.cookie = name + "=" + encodeURIComponent(value) + ";expires=" + date.toUTCString() + ";path=/;secure";
|
||||
}
|
||||
removeCookie(name) {
|
||||
document.cookie = name + "=;Max-Age=-99999999;";
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=Cookies.js.map
|
@ -0,0 +1 @@
|
||||
{"version":3,"file":"Cookies.js","sourceRoot":"","sources":["../../../TypeScripts/Base/Services/Cookies.ts"],"names":[],"mappings":"AAGA,MAAM,OAAO,OAAO;IAOhB,SAAS,CAAC,UAAkB;QAExB,MAAM,IAAI,GAAQ,UAAU,GAAG,GAAG,CAAC;QAEnC,MAAM,aAAa,GAAG,kBAAkB,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAE1D,MAAM,EAAE,GAAG,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAEpC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAEjC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;YAEd,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;gBAEzB,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;YACvB,CAAC;YAED,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;gBAExB,OAAO,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;YAC9C,CAAC;QACL,CAAC;QAED,OAAO,EAAE,CAAC;IACd,CAAC;IAOD,SAAS,CAAC,IAAY,EAAE,KAAa,EAAE,IAAY;QAG/C,MAAM,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;QAGxB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QAG1D,QAAQ,CAAC,MAAM,GAAG,IAAI,GAAG,GAAG,GAAG,kBAAkB,CAAC,KAAK,CAAC,GAAG,WAAW,GAAG,IAAI,CAAC,WAAW,EAAE,GAAG,gBAAgB,CAAC;IACnH,CAAC;IAMD,YAAY,CAAC,IAAY;QACrB,QAAQ,CAAC,MAAM,GAAG,IAAI,GAAG,sBAAsB,CAAC;IACpD,CAAC;CACJ"}
|
143
APP_WEB/ScriptsAndCss/JsScripts/Base/Services/Utilities.js
Normal file
143
APP_WEB/ScriptsAndCss/JsScripts/Base/Services/Utilities.js
Normal file
@ -0,0 +1,143 @@
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
import { Alerts } from "./Alerts/Alerts";
|
||||
export class Utilities {
|
||||
constructor() {
|
||||
this.Alerts = new Alerts();
|
||||
}
|
||||
isEmpty(value) {
|
||||
if (value == null)
|
||||
return true;
|
||||
if (value === "")
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
setInputWarning(input) {
|
||||
input.classList.add("warning_input");
|
||||
const timeout = setTimeout(() => {
|
||||
input.classList.remove("warning_input");
|
||||
clearTimeout(timeout);
|
||||
}, 3000);
|
||||
}
|
||||
setAreaWarning(input) {
|
||||
input.classList.add("warning_area");
|
||||
const timeout = setTimeout(() => {
|
||||
input.classList.remove("warning_area");
|
||||
clearTimeout(timeout);
|
||||
}, 3000);
|
||||
}
|
||||
isValidEmail(email) {
|
||||
if (this.isEmpty(email))
|
||||
return false;
|
||||
const pattern = /^([a-z0-9_.-])+@[a-z0-9-]+\.([a-z]{2,4}\.)?[a-z]{2,4}$/i;
|
||||
return pattern.test(email);
|
||||
}
|
||||
doDelay(mlsec) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
return new Promise(resolve => {
|
||||
setTimeout(() => {
|
||||
resolve(null);
|
||||
}, mlsec);
|
||||
});
|
||||
});
|
||||
}
|
||||
get getWidh() {
|
||||
return window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
|
||||
}
|
||||
get getHeight() {
|
||||
return window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
|
||||
}
|
||||
getRandomInt(min, max) {
|
||||
min = Math.ceil(min);
|
||||
max = Math.floor(max);
|
||||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
}
|
||||
copyValueToBuffer(value, element) {
|
||||
try {
|
||||
const coord = element.getBoundingClientRect();
|
||||
const scrolled = window.pageYOffset || document.documentElement.scrollTop;
|
||||
const iOsDevice = navigator.userAgent.match(/ipad|iphone/i);
|
||||
const textArea = document.createElement("textarea");
|
||||
textArea.readOnly = true;
|
||||
textArea.style.top = `${Math.round(scrolled + coord.top)}px`;
|
||||
textArea.classList.add("text_copy");
|
||||
textArea.value = value;
|
||||
document.body.appendChild(textArea);
|
||||
textArea.focus();
|
||||
if (iOsDevice) {
|
||||
const editable = textArea.contentEditable;
|
||||
const readOnly = textArea.readOnly;
|
||||
textArea.contentEditable = "true";
|
||||
textArea.readOnly = false;
|
||||
const range = document.createRange();
|
||||
range.selectNodeContents(textArea);
|
||||
const selection = window.getSelection();
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
textArea.setSelectionRange(0, 999999);
|
||||
textArea.contentEditable = editable;
|
||||
textArea.readOnly = readOnly;
|
||||
}
|
||||
else {
|
||||
textArea.select();
|
||||
}
|
||||
const resultCopy = document.execCommand("copy");
|
||||
document.body.removeChild(textArea);
|
||||
return resultCopy;
|
||||
}
|
||||
catch (e) {
|
||||
console.error("Error: ", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
getCurrentDate() {
|
||||
const date = new Date();
|
||||
const nowDay = date.getDate();
|
||||
const nowMonth = date.getMonth() + 1;
|
||||
let forFullDay = "";
|
||||
if (nowDay < 10) {
|
||||
forFullDay = "0";
|
||||
}
|
||||
let forFullMonth = "";
|
||||
if (nowMonth < 10) {
|
||||
forFullMonth = "0";
|
||||
}
|
||||
return `${forFullDay}${nowDay}.${forFullMonth}${nowMonth}.${date.getFullYear()}`;
|
||||
}
|
||||
stringToBoolean(str) {
|
||||
const lowerStr = str.toLowerCase();
|
||||
if (lowerStr === "true") {
|
||||
return true;
|
||||
}
|
||||
else if (lowerStr === "false") {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
generateUuid() {
|
||||
var d = new Date().getTime();
|
||||
var d2 = ((typeof performance !== "undefined") && performance.now && (performance.now() * 1000)) || 0;
|
||||
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, c => {
|
||||
var r = Math.random() * 16;
|
||||
if (d > 0) {
|
||||
r = (d + r) % 16 | 0;
|
||||
d = Math.floor(d / 16);
|
||||
}
|
||||
else {
|
||||
r = (d2 + r) % 16 | 0;
|
||||
d2 = Math.floor(d2 / 16);
|
||||
}
|
||||
return (c === "x" ? r : (r & 0x3 | 0x8)).toString(16);
|
||||
});
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=Utilities.js.map
|
@ -0,0 +1 @@
|
||||
{"version":3,"file":"Utilities.js","sourceRoot":"","sources":["../../../TypeScripts/Base/Services/Utilities.ts"],"names":[],"mappings":"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"}
|
61
APP_WEB/ScriptsAndCss/JsScripts/Pages/Base/BasePage.js
Normal file
61
APP_WEB/ScriptsAndCss/JsScripts/Pages/Base/BasePage.js
Normal file
@ -0,0 +1,61 @@
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
import { TypeAlert } from "../../Base/Services/Alerts/Alerts";
|
||||
export class BasePage {
|
||||
constructor(utilities, cookies, alerts) {
|
||||
this.Utilities = utilities;
|
||||
this.Cookies = cookies;
|
||||
this.Alerts = alerts;
|
||||
}
|
||||
set PageReadyState(state) {
|
||||
if (this.readyState !== state) {
|
||||
this.readyState = state;
|
||||
const event = new CustomEvent('pageStateChanged', {
|
||||
detail: {
|
||||
stateName: 'ReadyState',
|
||||
stateValue: state
|
||||
}
|
||||
});
|
||||
window.dispatchEvent(event);
|
||||
}
|
||||
}
|
||||
get PageReadyState() {
|
||||
return this.readyState;
|
||||
}
|
||||
WaitForReadyState(conditions, actions) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
return new Promise((resolve) => {
|
||||
const intervalId = setInterval(() => {
|
||||
const allConditionsMet = conditions.every(condition => condition === true);
|
||||
if (allConditionsMet) {
|
||||
clearInterval(intervalId);
|
||||
if (allConditionsMet) {
|
||||
this.PageReadyState = true;
|
||||
actions.forEach(action => {
|
||||
action();
|
||||
});
|
||||
const alert = {
|
||||
text: "Страница успешно запущена",
|
||||
type: TypeAlert.Ok,
|
||||
duration: 2
|
||||
};
|
||||
this.Alerts.AlertShow(alert);
|
||||
resolve({ states: conditions });
|
||||
}
|
||||
else {
|
||||
console.log("Состояния еще не доступны или не достигнута готовность...");
|
||||
}
|
||||
}
|
||||
}, 100);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=BasePage.js.map
|
@ -0,0 +1 @@
|
||||
{"version":3,"file":"BasePage.js","sourceRoot":"","sources":["../../../TypeScripts/Pages/Base/BasePage.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAU,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAKtE,MAAM,OAAO,QAAQ;IA0BjB,YAAY,SAAoB,EAAE,OAAgB,EAAE,MAAc;QAE9D,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAG3B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QAGvB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACzB,CAAC;IAKD,IAAW,cAAc,CAAC,KAAK;QAC3B,IAAI,IAAI,CAAC,UAAU,KAAK,KAAK,EAAE,CAAC;YAC5B,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;YAExB,MAAM,KAAK,GAAG,IAAI,WAAW,CAA6B,kBAAkB,EAAE;gBAC1E,MAAM,EAAE;oBACJ,SAAS,EAAE,YAAY;oBACvB,UAAU,EAAE,KAAK;iBACpB;aACJ,CAAC,CAAC;YAEH,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;IACL,CAAC;IAKD,IAAW,cAAc;QACrB,OAAO,IAAI,CAAC,UAAU,CAAC;IAC3B,CAAC;IAQY,iBAAiB,CAAC,UAAqB,EAAE,OAAuB;;YACzE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;gBAC3B,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,EAAE;oBAEhC,MAAM,gBAAgB,GAAG,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS,KAAK,IAAI,CAAC,CAAC;oBAE3E,IAAI,gBAAgB,EAAE,CAAC;wBACnB,aAAa,CAAC,UAAU,CAAC,CAAC;wBAE1B,IAAI,gBAAgB,EAAE,CAAC;4BACnB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;4BAK3B,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;gCACrB,MAAM,EAAE,CAAC;4BACb,CAAC,CAAC,CAAC;4BAGH,MAAM,KAAK,GAAsB;gCAC7B,IAAI,EAAE,2BAA2B;gCACjC,IAAI,EAAE,SAAS,CAAC,EAAE;gCAClB,QAAQ,EAAE,CAAC;6BACd,CAAC;4BAEF,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;4BAE5B,OAAO,CAAC,EAAE,MAAM,EAAE,UAAU,EAAC,CAAC,CAAC;wBACnC,CAAC;6BAAM,CAAC;4BACJ,OAAO,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAC;wBAC7E,CAAC;oBACL,CAAC;gBACL,CAAC,EAAE,GAAG,CAAC,CAAC;YACZ,CAAC,CAAC,CAAC;QACP,CAAC;KAAA;CACJ"}
|
18
APP_WEB/ScriptsAndCss/JsScripts/Pages/Contacts.js
Normal file
18
APP_WEB/ScriptsAndCss/JsScripts/Pages/Contacts.js
Normal file
@ -0,0 +1,18 @@
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
import { BasePage } from "./Base/BasePage";
|
||||
export class ContactPage extends BasePage {
|
||||
StartPage() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
yield this.WaitForReadyState([true], []);
|
||||
});
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=Contacts.js.map
|
1
APP_WEB/ScriptsAndCss/JsScripts/Pages/Contacts.js.map
Normal file
1
APP_WEB/ScriptsAndCss/JsScripts/Pages/Contacts.js.map
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"Contacts.js","sourceRoot":"","sources":["../../TypeScripts/Pages/Contacts.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE3C,MAAM,OAAO,WAAY,SAAQ,QAAQ;IAIxB,SAAS;;YAClB,MAAM,IAAI,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QAC7C,CAAC;KAAA;CACJ"}
|
18
APP_WEB/ScriptsAndCss/JsScripts/Pages/IndexPage.js
Normal file
18
APP_WEB/ScriptsAndCss/JsScripts/Pages/IndexPage.js
Normal file
@ -0,0 +1,18 @@
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
import { BasePage } from "./Base/BasePage";
|
||||
export class IndexPage extends BasePage {
|
||||
StartPage() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
yield this.WaitForReadyState([true], []);
|
||||
});
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=IndexPage.js.map
|
1
APP_WEB/ScriptsAndCss/JsScripts/Pages/IndexPage.js.map
Normal file
1
APP_WEB/ScriptsAndCss/JsScripts/Pages/IndexPage.js.map
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"IndexPage.js","sourceRoot":"","sources":["../../TypeScripts/Pages/IndexPage.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE3C,MAAM,OAAO,SAAU,SAAQ,QAAQ;IAItB,SAAS;;YAClB,MAAM,IAAI,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QAC7C,CAAC;KAAA;CACJ"}
|
@ -7,23 +7,56 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
import { Cookies } from "./cookies";
|
||||
import { Utilities } from "./utilities";
|
||||
import { Alerts } from "./Base/Services/Alerts/Alerts";
|
||||
import { Cookies } from "./Base/Services/Cookies";
|
||||
import { Utilities } from "./Base/Services/Utilities";
|
||||
import { ContactPage } from "./Pages/Contacts";
|
||||
import { IndexPage } from "./Pages/IndexPage";
|
||||
(() => {
|
||||
window.addEventListener("load", () => __awaiter(void 0, void 0, void 0, function* () {
|
||||
const utilities = new Utilities();
|
||||
const cookies = new Cookies();
|
||||
const alerts = new Alerts();
|
||||
const currentUrl = new URL(document.location.href);
|
||||
const pathname = currentUrl.pathname.toLowerCase();
|
||||
const partsPath = pathname.split("/");
|
||||
let indexPageState = {
|
||||
ReadyState: undefined
|
||||
};
|
||||
window.addEventListener('pageStateChanged', function (event) {
|
||||
const stateName = event.detail.stateName;
|
||||
const stateValue = event.detail.stateValue;
|
||||
if (stateName === 'ReadyState') {
|
||||
indexPageState.ReadyState = stateValue;
|
||||
}
|
||||
CheckStatesAndProceed();
|
||||
});
|
||||
switch (partsPath[1]) {
|
||||
case "":
|
||||
{
|
||||
const page = new IndexPage(utilities, cookies, alerts);
|
||||
yield page.StartPage();
|
||||
}
|
||||
break;
|
||||
case "":
|
||||
{
|
||||
const page = new ContactPage(utilities, cookies, alerts);
|
||||
yield page.StartPage();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
function CheckStatesAndProceed() {
|
||||
if (indexPageState.ReadyState !== undefined) {
|
||||
if (indexPageState.ReadyState) {
|
||||
console.log("Success Start Page");
|
||||
}
|
||||
else {
|
||||
console.log("Wait Load Page");
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
})();
|
||||
//# sourceMappingURL=main_api.js.map
|
@ -1 +1 @@
|
||||
{"version":3,"file":"main_api.js","sourceRoot":"","sources":["../TypeScripts/main_api.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,CAAC,GAAG,EAAE;IAEF,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,GAAS,EAAE;QAEvC,MAAM,SAAS,GAAG,IAAI,SAAS,EAAE,CAAC;QAGlC,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;QAG9B,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAGnD,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;QAGnD,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAGtC,QAAQ,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;YACnB,KAAK,EAAE;gBACH,CAAC;gBAKD,CAAC;gBACD,MAAM;YACV;gBACI,MAAM;QACd,CAAC;IACL,CAAC,CAAA,CAAC,CAAC;AACP,CAAC,CAAC,EAAE,CAAC"}
|
||||
{"version":3,"file":"main_api.js","sourceRoot":"","sources":["../TypeScripts/main_api.ts"],"names":[],"mappings":";;;;;;;;;AACA,OAAO,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAE9C,CAAC,GAAG,EAAE;IAEF,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,GAAS,EAAE;QAEvC,MAAM,SAAS,GAAG,IAAI,SAAS,EAAE,CAAC;QAGlC,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;QAG9B,MAAM,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;QAG5B,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAGnD,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;QAGnD,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAGtC,IAAI,cAAc,GAAG;YACjB,UAAU,EAAE,SAAS;SACxB,CAAC;QAEF,MAAM,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,UAAU,KACX;YACvC,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC;YACzC,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC;YAE3C,IAAI,SAAS,KAAK,YAAY,EAAE,CAAC;gBAC7B,cAAc,CAAC,UAAU,GAAG,UAAU,CAAC;YAC3C,CAAC;YAED,qBAAqB,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;QAGH,QAAQ,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;YACnB,KAAK,EAAE;gBACH,CAAC;oBAEG,MAAM,IAAI,GAAG,IAAI,SAAS,CAAC,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;oBAEvD,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;gBAC3B,CAAC;gBACD,MAAM;YAEV,KAAK,EAAE;gBACH,CAAC;oBAEG,MAAM,IAAI,GAAG,IAAI,WAAW,CAAC,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;oBAEzD,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;gBAC3B,CAAC;gBACD,MAAM;YACV;gBACI,MAAM;QACd,CAAC;QAED,SAAS,qBAAqB;YAC1B,IAAI,cAAc,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;gBAE1C,IAAI,cAAc,CAAC,UAAU,EAAE,CAAC;oBAC5B,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;gBACtC,CAAC;qBAAM,CAAC;oBACJ,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;gBAClC,CAAC;YACL,CAAC;QACL,CAAC;IACL,CAAC,CAAA,CAAC,CAAC;AACP,CAAC,CAAC,EAAE,CAAC"}
|
@ -0,0 +1,4 @@
|
||||
export interface PageReadyStateChangedEvent {
|
||||
stateName: string;
|
||||
stateValue: any;
|
||||
}
|
@ -1,10 +1,8 @@
|
||||
export class Alerts {
|
||||
/**
|
||||
* Функция для отображения уведомления
|
||||
*
|
||||
* TODO: Сделать синхронизацию уведомления для всех - если она касается размещения задач на сервере
|
||||
*/
|
||||
public AlertShow(notification: Notification): void {
|
||||
public AlertShow(notification: NotificationAlert): void {
|
||||
const container = document.getElementById('notification-container');
|
||||
if (!container) return;
|
||||
|
||||
@ -37,15 +35,23 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Тип для уведомлений
|
||||
interface Notification {
|
||||
text: string;
|
||||
declare global {
|
||||
/**
|
||||
* Уведомление
|
||||
*/
|
||||
interface NotificationAlert {
|
||||
text: string; // текст сообщения уведомления
|
||||
duration: number; // продолжительность отображения в секундах
|
||||
type: TypeAlert;
|
||||
type: TypeAlert; // тип уведомления (расцветка)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Тип оповещения
|
||||
*/
|
||||
export enum TypeAlert {
|
||||
Error = 'error',
|
||||
Warning = 'warning',
|
||||
Ok = 'ok',
|
||||
Ok = 'ok'
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
import { Alerts } from "./alerts";
|
||||
import { Alerts } from "./Alerts/Alerts";
|
||||
|
||||
/**
|
||||
* Класс вспомогательных методов
|
110
APP_WEB/ScriptsAndCss/TypeScripts/Pages/Base/BasePage.ts
Normal file
110
APP_WEB/ScriptsAndCss/TypeScripts/Pages/Base/BasePage.ts
Normal file
@ -0,0 +1,110 @@
|
||||
import { Alerts, TypeAlert } from "../../Base/Services/Alerts/Alerts";
|
||||
import { PageReadyStateChangedEvent } from "../../Base/Components/BaseEvents";
|
||||
import { Utilities } from "../../Base/Services/Utilities";
|
||||
import { Cookies } from "../../Base/Services/Cookies";
|
||||
|
||||
export class BasePage {
|
||||
/**
|
||||
* Экземпляр класса утилит
|
||||
*/
|
||||
public readonly Utilities: Utilities;
|
||||
|
||||
/**
|
||||
* Экземпляр класса кук
|
||||
*/
|
||||
public readonly Cookies: Cookies;
|
||||
|
||||
/**
|
||||
* Экземпляр класса системы уведомлений
|
||||
*/
|
||||
public readonly Alerts: Alerts;
|
||||
|
||||
/**
|
||||
* Состояние готовности страницы
|
||||
*/
|
||||
private readyState: boolean;
|
||||
|
||||
/**
|
||||
* Конструктор
|
||||
* @param utilities - экземпляр класса утилит
|
||||
* @param cookies - экземпляр класса кук
|
||||
*/
|
||||
constructor(utilities: Utilities, cookies: Cookies, alerts: Alerts) {
|
||||
//присваиваем экземпляр класса утилит
|
||||
this.Utilities = utilities;
|
||||
|
||||
//присваиваем экземпляр класса кук
|
||||
this.Cookies = cookies;
|
||||
|
||||
//присваиваем экземпляр класса кук
|
||||
this.Alerts = alerts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Метод изменяет состояние готовности страницы
|
||||
*/
|
||||
public set PageReadyState(state) {
|
||||
if (this.readyState !== state) {
|
||||
this.readyState = state;
|
||||
// Создаем и отправляем CustomEvent
|
||||
const event = new CustomEvent<PageReadyStateChangedEvent>('pageStateChanged', {
|
||||
detail: {
|
||||
stateName: 'ReadyState',
|
||||
stateValue: state
|
||||
}
|
||||
});
|
||||
|
||||
window.dispatchEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Метод получает состояние готовности страницы
|
||||
*/
|
||||
public get PageReadyState() {
|
||||
return this.readyState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Метод ждёт состояния готовности страницы к показу пользователю
|
||||
* P.s на ней могут работать разные сервисы или запускаться перед началом работы со страницей
|
||||
* @param conditions - массив булевых условий, которые должны быть истинными
|
||||
* @param actions - массив отложенных функций, которые будут выполнены по очереди после выполнения всех условий
|
||||
*/
|
||||
public async WaitForReadyState(conditions: boolean[], actions: (() => void)[]) {
|
||||
return new Promise((resolve) => {
|
||||
const intervalId = setInterval(() => {
|
||||
// Проверяем все условия готовности
|
||||
const allConditionsMet = conditions.every(condition => condition === true);
|
||||
|
||||
if (allConditionsMet) {
|
||||
clearInterval(intervalId); // Останавливаем интервал
|
||||
|
||||
if (allConditionsMet) {
|
||||
this.PageReadyState = true;
|
||||
|
||||
/*
|
||||
После того как все условия выполнены, выполняем отложенные функции по очереди
|
||||
*/
|
||||
actions.forEach(action => {
|
||||
action(); // Выполняем каждую отложенную функцию
|
||||
});
|
||||
|
||||
// Пример использования NotificationAlert и TypeAlert
|
||||
const alert: NotificationAlert = {
|
||||
text: "Страница успешно запущена",
|
||||
type: TypeAlert.Ok,
|
||||
duration: 2
|
||||
};
|
||||
|
||||
this.Alerts.AlertShow(alert)
|
||||
|
||||
resolve({ states: conditions});
|
||||
} else {
|
||||
console.log("Состояния еще не доступны или не достигнута готовность...");
|
||||
}
|
||||
}
|
||||
}, 100); // Проверяем каждые 100 мс
|
||||
});
|
||||
}
|
||||
}
|
14
APP_WEB/ScriptsAndCss/TypeScripts/Pages/Contacts.ts
Normal file
14
APP_WEB/ScriptsAndCss/TypeScripts/Pages/Contacts.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { BasePage } from "./Base/BasePage";
|
||||
|
||||
export class ContactPage extends BasePage {
|
||||
/**
|
||||
* Метод запускает страницу
|
||||
*/
|
||||
public async StartPage(): Promise<void> {
|
||||
await this.WaitForReadyState([true], [this.PostEventLoad]);
|
||||
}
|
||||
|
||||
private PostEventLoad(): void {
|
||||
console.log("Contact post event...")
|
||||
}
|
||||
}
|
14
APP_WEB/ScriptsAndCss/TypeScripts/Pages/IndexPage.ts
Normal file
14
APP_WEB/ScriptsAndCss/TypeScripts/Pages/IndexPage.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { BasePage } from "./Base/BasePage";
|
||||
|
||||
export class IndexPage extends BasePage {
|
||||
/**
|
||||
* Метод запускает страницу
|
||||
*/
|
||||
public async StartPage(): Promise<void> {
|
||||
await this.WaitForReadyState([true], [ this.PostEventLoad ]);
|
||||
}
|
||||
|
||||
private PostEventLoad(): void {
|
||||
console.log("Index post event...")
|
||||
}
|
||||
}
|
@ -1,5 +1,9 @@
|
||||
import { Cookies } from "./cookies";
|
||||
import { Utilities } from "./utilities";
|
||||
import { PageReadyStateChangedEvent } from "./Base/Components/BaseEvents";
|
||||
import { Alerts } from "./Base/Services/Alerts/Alerts";
|
||||
import { Cookies } from "./Base/Services/Cookies";
|
||||
import { Utilities } from "./Base/Services/Utilities";
|
||||
import { ContactPage } from "./Pages/Contacts";
|
||||
import { IndexPage } from "./Pages/IndexPage";
|
||||
|
||||
(() => {
|
||||
//по загрузке окна
|
||||
@ -10,6 +14,9 @@ import { Utilities } from "./utilities";
|
||||
//создаем экземпляр класса кук
|
||||
const cookies = new Cookies();
|
||||
|
||||
//создаем экземпляр класса уведомлений
|
||||
const alerts = new Alerts();
|
||||
|
||||
//получаем текущий URL
|
||||
const currentUrl = new URL(document.location.href);
|
||||
|
||||
@ -19,18 +26,54 @@ import { Utilities } from "./utilities";
|
||||
//разбиваем пути URL на части
|
||||
const partsPath = pathname.split("/");
|
||||
|
||||
// Состояние IndexPage, изначально неопределенное
|
||||
let indexPageState = {
|
||||
ReadyState: undefined
|
||||
};
|
||||
|
||||
window.addEventListener('pageStateChanged', function (event:
|
||||
CustomEvent<PageReadyStateChangedEvent>) {
|
||||
const stateName = event.detail.stateName;
|
||||
const stateValue = event.detail.stateValue;
|
||||
|
||||
if (stateName === 'ReadyState') {
|
||||
indexPageState.ReadyState = stateValue;
|
||||
}
|
||||
|
||||
CheckStatesAndProceed();
|
||||
});
|
||||
|
||||
//смотрим путь
|
||||
switch (partsPath[1]) {
|
||||
case "": //страница авторизации
|
||||
case "":
|
||||
{
|
||||
//создаем экземпляр класса авторизации
|
||||
//const auth = new IndexPage(utilities, cookies);
|
||||
////запускаем авторизацию
|
||||
//await auth.startPage();
|
||||
// создаем экземпляр страницы
|
||||
const page = new IndexPage(utilities, cookies, alerts);
|
||||
// запускаем
|
||||
await page.StartPage();
|
||||
}
|
||||
break;
|
||||
case "contacts":
|
||||
{
|
||||
// создаем экземпляр страницы
|
||||
const page = new ContactPage(utilities, cookies, alerts);
|
||||
// запускаем
|
||||
await page.StartPage();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
function CheckStatesAndProceed() {
|
||||
if (indexPageState.ReadyState !== undefined) {
|
||||
// Все необходимые состояния получены
|
||||
if (indexPageState.ReadyState) {
|
||||
console.log("Success Start Page");
|
||||
} else {
|
||||
console.log("Wait Load Page");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
})();
|
4
APP_WEB/Views/Home/Contacts.cshtml
Normal file
4
APP_WEB/Views/Home/Contacts.cshtml
Normal file
@ -0,0 +1,4 @@
|
||||
@{
|
||||
ViewData["Title"] = "Контакты";
|
||||
}
|
||||
|
@ -1,8 +1,4 @@
|
||||
@{
|
||||
ViewData["Title"] = "Home Page";
|
||||
ViewData["Title"] = "Главная";
|
||||
}
|
||||
|
||||
<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>
|
||||
|
@ -3,20 +3,29 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>@ViewData["Title"] - AppWeb</title>
|
||||
<title>@ViewData["Title"]</title>
|
||||
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
|
||||
<link rel="stylesheet" href="~/css/app.min.css" asp-append-version="true" />
|
||||
<link rel="stylesheet" href="~/AppWeb.styles.css" asp-append-version="true" />
|
||||
<script src="~/js/app.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<main role="main" class="pb-3">
|
||||
@RenderBody()
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<div id="notification-container"></div> <!-- Контейнер для уведомлений -->
|
||||
|
||||
<!--Start Example Svg Icons-->
|
||||
@* <div class="hidden">
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<symbol viewBox="0 0 512 512" xml:space="preserve" id="menu" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M256 0C114.617 0 0 114.618 0 256c0 141.383 114.617 256 256 256 141.382 0 256-114.617 256-256C512 114.618 397.382 0 256 0zm117.649 366.297H138.351V322.18h235.298v44.117zm0-88.242H138.351v-44.102h235.298v44.102zm0-88.227H138.351v-44.117h235.298v44.117z" />
|
||||
</symbol>
|
||||
</svg>
|
||||
</div> *@
|
||||
<!--End svg icons-->
|
||||
|
||||
<script src="~/lib/jquery/dist/jquery.min.js"></script>
|
||||
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<script src="~/js/app.min.js" asp-append-version="true"></script>
|
||||
@await RenderSectionAsync("Scripts", required: false)
|
||||
</body>
|
||||
</html>
|
||||
|
148
APP_WEB/wwwroot/css/app.min.css
vendored
148
APP_WEB/wwwroot/css/app.min.css
vendored
@ -1 +1,147 @@
|
||||
html{font-size:14px}@media (min-width:768px){html{font-size:16px}}.btn-link.nav-link:focus,.btn:active:focus,.btn:focus,.form-check-input:focus,.form-control:focus{box-shadow:0 0 0 .1rem #fff,0 0 0 .25rem #258cfb}html{min-height:100%;position:relative}body{margin-bottom:60px}
|
||||
/*!*************************************************************************************!*\
|
||||
!*** css ./node_modules/css-loader/dist/cjs.js!./ScriptsAndCss/CssFiles/styles.css ***!
|
||||
\*************************************************************************************/
|
||||
html {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
html {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
|
||||
box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
|
||||
}
|
||||
|
||||
html {
|
||||
position: relative;
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin-bottom: 60px;
|
||||
}
|
||||
|
||||
/*
|
||||
**************************
|
||||
START ALERT
|
||||
**************************
|
||||
*/
|
||||
|
||||
/* Основные стили для контейнера уведомлений */
|
||||
#notification-container {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
left: 20px;
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.error_alert_animate {
|
||||
border: 1px solid #AC0B00;
|
||||
}
|
||||
|
||||
.ok_alert_animate {
|
||||
border: 1px solid #007126;
|
||||
}
|
||||
|
||||
.warning_alert_animate {
|
||||
border: 1px solid #A33E00;
|
||||
}
|
||||
|
||||
/* Стили для уведомлений */
|
||||
.notification {
|
||||
background-color: #333;
|
||||
color: white;
|
||||
border-radius: 8px;
|
||||
padding: 10px 20px;
|
||||
margin-bottom: 10px;
|
||||
font-size: 16px;
|
||||
max-width: 300px;
|
||||
opacity: 1;
|
||||
animation: slideUpAndFade 5s ease-in-out forwards;
|
||||
}
|
||||
|
||||
/* Анимация для подъема уведомления вверх и его исчезновения */
|
||||
@keyframes slideUpAndFade {
|
||||
0% {
|
||||
transform: translateY(0);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: translateY(-50%); /* Поднимаем уведомление до середины экрана */
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translateY(-100%); /* Двигаем уведомление еще выше */
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
**************************
|
||||
END ALERT
|
||||
**************************
|
||||
*/
|
||||
|
||||
/*
|
||||
**************************
|
||||
START ANIMS
|
||||
**************************
|
||||
*/
|
||||
|
||||
|
||||
.puff-in-center {
|
||||
-webkit-animation: puff-in-center 0.1s cubic-bezier(0.470, 0.000, 0.745, 0.715) both;
|
||||
animation: puff-in-center 0.1s cubic-bezier(0.470, 0.000, 0.745, 0.715) both;
|
||||
}
|
||||
|
||||
/**
|
||||
* ----------------------------------------
|
||||
* animation puff-in-center
|
||||
* ----------------------------------------
|
||||
*/
|
||||
@-webkit-keyframes puff-in-center {
|
||||
0% {
|
||||
-webkit-transform: scale(2);
|
||||
transform: scale(2);
|
||||
-webkit-filter: blur(4px);
|
||||
filter: blur(4px);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
100% {
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
-webkit-filter: blur(0px);
|
||||
filter: blur(0px);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes puff-in-center {
|
||||
0% {
|
||||
-webkit-transform: scale(2);
|
||||
transform: scale(2);
|
||||
-webkit-filter: blur(4px);
|
||||
filter: blur(4px);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
100% {
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
-webkit-filter: blur(0px);
|
||||
filter: blur(0px);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
**************************
|
||||
END ANIMS
|
||||
**************************
|
||||
*/
|
||||
|
147
APP_WEB/wwwroot/js/app.min.js
vendored
147
APP_WEB/wwwroot/js/app.min.js
vendored
File diff suppressed because one or more lines are too long
49
APP_WEB/wwwroot/js/styles.min.js
vendored
49
APP_WEB/wwwroot/js/styles.min.js
vendored
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
|
||||
* This devtool is neither made for production nor for readable output files.
|
||||
* It uses "eval()" calls to create a separate source file in the browser devtools.
|
||||
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
|
||||
* or disable the default devtool with "devtool: false".
|
||||
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
|
||||
*/
|
||||
/******/ (() => { // webpackBootstrap
|
||||
/******/ "use strict";
|
||||
/******/ var __webpack_modules__ = ({
|
||||
|
||||
/***/ "./ScriptsAndCss/CssFiles/styles.css":
|
||||
/*!*******************************************!*\
|
||||
!*** ./ScriptsAndCss/CssFiles/styles.css ***!
|
||||
\*******************************************/
|
||||
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
eval("__webpack_require__.r(__webpack_exports__);\n// extracted by mini-css-extract-plugin\n\n\n//# sourceURL=webpack://asp.net/./ScriptsAndCss/CssFiles/styles.css?");
|
||||
|
||||
/***/ })
|
||||
|
||||
/******/ });
|
||||
/************************************************************************/
|
||||
/******/ // The require scope
|
||||
/******/ var __webpack_require__ = {};
|
||||
/******/
|
||||
/************************************************************************/
|
||||
/******/ /* webpack/runtime/make namespace object */
|
||||
/******/ (() => {
|
||||
/******/ // define __esModule on exports
|
||||
/******/ __webpack_require__.r = (exports) => {
|
||||
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
||||
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
||||
/******/ }
|
||||
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
||||
/******/ };
|
||||
/******/ })();
|
||||
/******/
|
||||
/************************************************************************/
|
||||
/******/
|
||||
/******/ // startup
|
||||
/******/ // Load entry module and return exports
|
||||
/******/ // This entry module can't be inlined because the eval devtool is used.
|
||||
/******/ var __webpack_exports__ = {};
|
||||
/******/ __webpack_modules__["./ScriptsAndCss/CssFiles/styles.css"](0, __webpack_exports__, __webpack_require__);
|
||||
/******/
|
||||
/******/ })()
|
||||
;
|
463
README.md
463
README.md
@ -1,463 +0,0 @@
|
||||
# 🌁 Шаблон проекта ASP NET CORE MVC, Frontend - на TypeScript
|
||||
|
||||
## 🎇 Этапы наполнения конфигурациями 🎇
|
||||
|
||||
---
|
||||
1. ⛅ Импорт `tsconfig.json` ⛅
|
||||
---
|
||||
|
||||
<details>
|
||||
<summary>Раскрыть код tsconfig.json</summary>
|
||||
|
||||
```json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es2016", // Устанавливает уровень JavaScript, в который компилируется TypeScript (в данном случае ES2016).
|
||||
"module": "es6", // Определяет, какой модульный формат используется в процессе компиляции (ES6 модули).
|
||||
"moduleResolution": "node", // Способ разрешения модулей. В данном случае используется разрешение как в Node.js.
|
||||
"jsx": "preserve", // Как компилировать JSX. В данном случае оставляем JSX без изменений.
|
||||
"declaration": false, // Указывает, генерировать ли файлы типов (.d.ts). Здесь это отключено.
|
||||
"removeComments": true, // Указывает, что комментарии должны быть удалены из скомпилированного кода.
|
||||
"noImplicitAny": false, // Отключает предупреждения о неявных типах `any` в коде.
|
||||
"noEmitOnError": true, // Указывает, что компиляция должна быть остановлена, если есть ошибки.
|
||||
"sourceMap": true, // Генерирует карты исходных кодов для упрощения отладки.
|
||||
"esModuleInterop": true, // Включает совместимость с модулями ES при импорте CommonJS модулей.
|
||||
"experimentalDecorators": true, // Включает поддержку экспериментальных декораторов в TypeScript.
|
||||
"emitDecoratorMetadata": true, // Включает генерацию метаданных для декораторов, которые могут использоваться в таких библиотеках как TypeORM или Angular.
|
||||
"outDir": "ScriptsAndCss/JsScripts", // Указывает директорию для сохранения скомпилированных файлов.
|
||||
"lib": [ "es2016", "dom" ] // Указывает библиотеки, которые будут включены при компиляции (ES2016 и DOM).
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules" // Исключает папку node_modules из процесса компиляции.
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
2. ⛅ Импорт `webpack.config.js` ⛅
|
||||
---
|
||||
|
||||
<details>
|
||||
<summary>Раскрыть код webpack.config.js</summary>
|
||||
|
||||
```js
|
||||
const path = require('path');
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
|
||||
const TerserPlugin = require('terser-webpack-plugin'); // Импортируем TerserPlugin
|
||||
|
||||
module.exports = {
|
||||
entry: {
|
||||
app: './ScriptsAndCss/TypeScripts/main_api.ts', // Точка входа для JavaScript
|
||||
styles: './ScriptsAndCss/CssFiles/styles.css' // Точка входа для CSS (может быть любой CSS-файл)
|
||||
},
|
||||
output: {
|
||||
path: path.resolve(__dirname, 'wwwroot/js'),
|
||||
filename: '[name].min.js' // Используем [name] для динамического имени файла
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.ts', '.js', '.css'] // Добавили .css
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.ts$/,
|
||||
use: 'ts-loader',
|
||||
exclude: /node_modules/
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: [
|
||||
MiniCssExtractPlugin.loader, // Извлекает CSS в отдельные файлы
|
||||
'css-loader' // Обрабатывает @import и url()
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
new MiniCssExtractPlugin({
|
||||
filename: '../css/app.min.css' // Куда Webpack должен поместить CSS-файл
|
||||
})
|
||||
],
|
||||
mode: 'development',
|
||||
watch: true,
|
||||
};
|
||||
```
|
||||
|
||||
</details>
|
||||
<br>
|
||||
|
||||
> В случае публикации в Production релиза нужно сменить режим `mode: 'development'` на `mode: 'production'` в файле конфигурации
|
||||
|
||||
<details>
|
||||
<summary>Раскрыть код изменений webpack.config.js</summary>
|
||||
|
||||
```js
|
||||
mode: 'production', // Изменен режим на production для минимизации
|
||||
optimization: {
|
||||
minimize: true, // Включаем минимизацию
|
||||
minimizer: [
|
||||
new TerserPlugin(), // Плагин для минимизации JS
|
||||
new CssMinimizerPlugin() // Плагин для минимизации CSS
|
||||
]
|
||||
},
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
3. ⛅ Импорт `package.json` - ряд плагинов опционален под ваш проект ⛅
|
||||
---
|
||||
|
||||
<details>
|
||||
<summary>Раскрыть код package.json</summary>
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"name": "asp.net",
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"css-minimizer-webpack-plugin": "7.0.0",
|
||||
"terser-webpack-plugin": "5.3.12",
|
||||
"cytoscape": "^3.31.0",
|
||||
"cytoscape-cose-bilkent": "4.1.0",
|
||||
"grunt": "1.4.1",
|
||||
"style-loader": "^4.0.0",
|
||||
"css-loader": "^7.1.2",
|
||||
"mini-css-extract-plugin": "^2.9.2",
|
||||
"grunt-webpack": "^7.0.0",
|
||||
"webpack-cli": "^6.0.1",
|
||||
"ts-loader": "^9.5.2",
|
||||
"browser-sync": "^3.0.3",
|
||||
"grunt-browser-sync": "^2.2.0",
|
||||
"grunt-contrib-clean": "2.0.0",
|
||||
"grunt-contrib-concat": "2.0.0",
|
||||
"grunt-contrib-cssmin": "5.0.0",
|
||||
"grunt-contrib-uglify": "5.0.1",
|
||||
"grunt-contrib-watch": "1.1.0",
|
||||
"grunt-ts": "6.0.0-beta.22"
|
||||
},
|
||||
"dependencies": {
|
||||
"cytoscape": "^3.31.0"
|
||||
},
|
||||
"comments": {
|
||||
"version": "Указывает текущую версию вашего проекта.",
|
||||
"name": "Имя вашего проекта.",
|
||||
"private": "Указывает, что проект является приватным и не должен быть опубликован в npm.",
|
||||
"devDependencies": {
|
||||
"css-minimizer-webpack-plugin": "Плагин для минимизации CSS файлов в процессе сборки Webpack.",
|
||||
"terser-webpack-plugin": "Плагин для минимизации JavaScript с использованием Terser.",
|
||||
"cytoscape": "Библиотека для работы с графами и сетями.",
|
||||
"cytoscape-cose-bilkent": "Плагин для Cytoscape, который добавляет алгоритм планирования расположения узлов.",
|
||||
"grunt": "Система автоматизации задач для Node.js, например, для сборки, минификации и тестирования.",
|
||||
"style-loader": "Лоадер для инжекции CSS в DOM через теги `<style>` в процессе сборки.",
|
||||
"css-loader": "Лоадер для обработки CSS файлов и поддержки импорта других CSS или стилей.",
|
||||
"mini-css-extract-plugin": "Плагин для извлечения CSS в отдельные файлы, что улучшает производительность.",
|
||||
"grunt-webpack": "Плагин для интеграции Webpack с системой Grunt.",
|
||||
"webpack-cli": "CLI для работы с Webpack, позволяет запускать сборку через командную строку.",
|
||||
"ts-loader": "Лоадер для загрузки TypeScript файлов в Webpack.",
|
||||
"browser-sync": "Инструмент для синхронизации браузеров и автоперезагрузки в процессе разработки.",
|
||||
"grunt-browser-sync": "Плагин для интеграции BrowserSync с Grunt.",
|
||||
"grunt-contrib-clean": "Плагин для удаления файлов или папок перед выполнением задач.",
|
||||
"grunt-contrib-concat": "Плагин для конкатенации (объединения) файлов в один.",
|
||||
"grunt-contrib-cssmin": "Плагин для сжатия CSS файлов.",
|
||||
"grunt-contrib-uglify": "Плагин для сжатия JavaScript файлов (использует UglifyJS).",
|
||||
"grunt-contrib-watch": "Плагин для отслеживания изменений файлов и автоматического выполнения задач.",
|
||||
"grunt-ts": "Плагин для компиляции TypeScript файлов в Grunt."
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
4. ⛅ Импорт `Gruntfile.js` ⛅
|
||||
---
|
||||
|
||||
<details>
|
||||
<summary>Раскрыть код Gruntfile.js</summary>
|
||||
|
||||
```js
|
||||
const webpackConfig = require('./webpack.config.js');
|
||||
|
||||
module.exports = function (grunt) {
|
||||
grunt.initConfig({
|
||||
webpack: {
|
||||
options: webpackConfig,
|
||||
build: {
|
||||
}
|
||||
},
|
||||
browserSync: {
|
||||
dev: {
|
||||
bsFiles: {
|
||||
src: [
|
||||
'wwwroot/css/*.css',
|
||||
'wwwroot/js/app.min.js', // Webpack создает app.min.js
|
||||
'Views/**/*.cshtml'
|
||||
]
|
||||
},
|
||||
options: {
|
||||
watchTask: true,
|
||||
proxy: "localhost:5000" // Замените на свой локальный адрес
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
ts: {
|
||||
files: ['ScriptsAndCss/TypeScripts/**/*.ts'],
|
||||
tasks: ['webpack:build'], // Webpack компилирует и собирает
|
||||
options: {
|
||||
spawn: false,
|
||||
},
|
||||
},
|
||||
bsReload: {
|
||||
files: ['wwwroot/css/*.css', 'wwwroot/js/app.min.js', 'Views/**/*.cshtml'],
|
||||
options: {
|
||||
reload: true
|
||||
}
|
||||
}
|
||||
},
|
||||
clean: ["wwwroot/css/*", "wwwroot/js/*", "ScriptsAndCss/Combined/*"],
|
||||
cssmin: { //сжатие CSS
|
||||
css: {
|
||||
src: ["ScriptsAndCss/CssFiles/*"], //какой файл сжимать
|
||||
dest: "wwwroot/css/app.min.css" //сжатый выходной файл
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
grunt.loadNpmTasks('grunt-webpack');
|
||||
grunt.loadNpmTasks('grunt-browser-sync');
|
||||
grunt.loadNpmTasks('grunt-contrib-watch');
|
||||
grunt.loadNpmTasks('grunt-contrib-clean');
|
||||
grunt.loadNpmTasks('grunt-contrib-cssmin');
|
||||
|
||||
grunt.registerTask("build", ["clean", "webpack:build", "cssmin"]);
|
||||
grunt.registerTask("default", ["build", "browserSync:dev", "watch"]);
|
||||
};
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
4. ⛅ Импорт `app_configuration.json` ⛅
|
||||
---
|
||||
|
||||
<details>
|
||||
<summary>Раскрыть код app_configuration.json</summary>
|
||||
|
||||
```json
|
||||
{
|
||||
"appSettings": {
|
||||
"appHost": "localhost:8833"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
## 🎇 Этапы сборочного процесса 🎇
|
||||
|
||||
---
|
||||
- 🌋 Восстановить NPM пакеты
|
||||
---
|
||||
- 🌋 Настроить директории для генерации Frontend
|
||||
- в корне проекта где мы будем его внедрять создаём такуб структуру папок
|
||||
- 📁ScriptsAndCss
|
||||
- 📁〰️📁CssFiles
|
||||
- 📁〰️📁JsScripts
|
||||
- 📁〰️📁TypeScripts
|
||||
---
|
||||
- 🌋 Установить Nuget пакеты
|
||||
- **`TypeScript.MSBuild`**
|
||||
- **`AspNetCore.Mvc.Razor.RuntimeCompilation`**
|
||||
- **`Swashbuckle.AspNetCore.Swagger`**
|
||||
- **`Swashbuckle.AspNetCore.SwaggerGen`**
|
||||
- **`Swashbuckle.AspNetCore.SwaggerUI`**
|
||||
---
|
||||
- 🌋 В файле `Views/Shared/_Layout.cshtml` изменить адреса до `css` и `js` файлов так как теперь они называются **`app.min.css`** и **`app.min.js`**
|
||||
---
|
||||
- 🌋 Добавить простейшую точку входа `[js]` приложения в папку 📁ScriptsAndCss〰️>📁TypeScripts - **`main_api.ts`**
|
||||
|
||||
<details>
|
||||
<summary>Раскрыть код main_api.ts</summary>
|
||||
|
||||
```ts
|
||||
(() => {
|
||||
//по загрузке окна
|
||||
window.addEventListener("load", async () => {
|
||||
//получаем текущий URL
|
||||
const currentUrl = new URL(document.location.href);
|
||||
|
||||
//получаем путь из URL
|
||||
const pathname = currentUrl.pathname.toLowerCase();
|
||||
|
||||
//разбиваем пути URL на части
|
||||
const partsPath = pathname.split("/");
|
||||
|
||||
//смотрим путь
|
||||
switch (partsPath[1]) {
|
||||
case "": //страница авторизации
|
||||
{
|
||||
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
})();
|
||||
```
|
||||
|
||||
</details>
|
||||
<br>
|
||||
|
||||
---
|
||||
- 🌋 Добавить простейшую точку входа `[css]` приложения в папку 📁ScriptsAndCss〰️>📁CssFiles - **`style.css`**
|
||||
|
||||
|
||||
<details>
|
||||
<summary>Раскрыть код style.css</summary>
|
||||
|
||||
```ts
|
||||
// ваши стили - скопируйте из wwwroot то что там было
|
||||
```
|
||||
|
||||
</details>
|
||||
<br>
|
||||
|
||||
---
|
||||
- 🌋 Добавить примерно такое содержимое в **`Program.cs`**
|
||||
> Поясняю - в данном примере вырезано внесение `CSRF` токена в логику работы сервера а также `Middleware` отвечающий за обработку служб защиты от подделки запросов. Тут мы вносим лишь Swagger для генерации документации по API и конфигурационный файл декларирующий **`host`** и **`port`** вашего сервера принудительно.
|
||||
|
||||
<details>
|
||||
<summary>Раскрыть код Program.cs</summary>
|
||||
|
||||
```cs
|
||||
using System.Reflection;
|
||||
using System.Text.Json;
|
||||
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.OpenApi.Models;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
builder.Configuration.SetBasePath(Directory.GetCurrentDirectory())
|
||||
.AddJsonFile($"{LoggingExtensions.AppDir}/app_configuration.json");
|
||||
|
||||
builder.WebHost.UseUrls($"https://{builder.Configuration["appSettings:appHost"]}");
|
||||
|
||||
builder.Services.AddControllersWithViews();
|
||||
|
||||
#region В этом регионе объявляем сервисы
|
||||
|
||||
// Например
|
||||
// builder.Services.AddSingleton<ICashService, CashService>();
|
||||
|
||||
#endregion
|
||||
|
||||
builder.Services.Configure<JsonOptions>(options =>
|
||||
{
|
||||
options.JsonSerializerOptions.WriteIndented = true; //для красивого форматирования
|
||||
options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
|
||||
});
|
||||
|
||||
builder.Services.AddSwaggerGen(options =>
|
||||
{
|
||||
options.SwaggerDoc("v1", new OpenApiInfo
|
||||
{
|
||||
Title = "App API",
|
||||
Version = "1.0.0",
|
||||
Description = "Информация об API",
|
||||
Contact = new OpenApiContact
|
||||
{
|
||||
Name = "Dvurechensky"
|
||||
}
|
||||
});
|
||||
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
|
||||
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
|
||||
options.IncludeXmlComments(xmlPath);
|
||||
});
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
if (!app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseExceptionHandler("/Home/Error");
|
||||
app.UseHsts();
|
||||
}
|
||||
else
|
||||
{
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI(c =>
|
||||
{
|
||||
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Документация");
|
||||
c.RoutePrefix = "docs";
|
||||
});
|
||||
app.UseDeveloperExceptionPage(); //используем страницу исключений
|
||||
}
|
||||
|
||||
// app.UseHttpsRedirection();
|
||||
|
||||
app.UseStaticFiles();
|
||||
app.UseRouting();
|
||||
|
||||
app.UseAuthorization();
|
||||
|
||||
app.MapControllerRoute(
|
||||
name: "default",
|
||||
pattern: "{controller=Home}/{action=Index}/{id?}");
|
||||
|
||||
app.Run();
|
||||
```
|
||||
|
||||
</details>
|
||||
<br>
|
||||
|
||||
---
|
||||
- 🌋 В диспетчере выполнения задач выполнить задачу `default` для генерации файлов
|
||||
---
|
||||
- 🌋 В настройках проекта в разделе `Выходные данные` поставить галочку на `Файл документации` - `Создание файла, содержащего документацию по API` для успешной работы **`Swagger`**
|
||||
---
|
||||
|
||||
## 🎇 Итог 🎇
|
||||
|
||||
#### 📷 База 📷
|
||||
При успешном старте в данном примере мы получим сервер:
|
||||
- по адресу **`https://localhost:8833`**
|
||||
- документацию Swagger **`https://localhost:8833/docs/`**
|
||||
---
|
||||
#### 📷 Плюшки 📷
|
||||
---
|
||||
- в свою очередь при вёрстке `Typescript` и активированной задаче `default` в `Диспетчере выполнения задач` - в реальном времени будет перезагружаться страница и мы увидим новые изменения на `Frontned` - лицевой стороне Web-сервера после каждого сохранения файла в проекте
|
||||
- при установке параметров указанных для `production` версии в файле `webpack.config.js` мы можем собрать `Release` версию и опубликовать её в сеть в которой все файлы `css` и `js` будут сжаты и минимизированы для более быстрой и качественной работы сервера в сети
|
||||
- мы можем прикрутить любую существующую библиотеку NPM и использовать её в скриптах `Typescript` для создания качественного `Frontend` - состояние которого мы можем отслеживать в реальном времени при разработке. Typescript поддерживает последние возможности ECMAScript (например, async/await, декораторы, модули и т. д.), что делает код более современным и удобным.
|
||||
- используя ASP.NET Core MVC для серверной части (backend), позволяет создавать масштабируемые, производительные и безопасные веб-приложения
|
||||
- Typescript для фронтенда (frontend) обеспечивает типизацию и улучшение читаемости кода, предотвращая множество ошибок, которые могут возникнуть при использовании обычного JavaScript.
|
||||
---
|
||||
#### 📷 Примерный процесс разработки: 📷
|
||||
---
|
||||
🎃 Frontend (Typescript + Webpack):
|
||||
|
||||
🎈 Вы пишете код на Typescript, который потом компилируется с помощью Webpack.
|
||||
Webpack минифицирует и обрабатывает ваши файлы, генерирует отдельные чанки для кода, CSS и изображений.
|
||||
Grunt помогает автоматизировать задачи, такие как запуск Webpack, минификация CSS/JS, запуск локального сервера с BrowserSync.
|
||||
Backend (ASP.NET Core MVC):
|
||||
|
||||
🎈 Серверная часть обрабатывает бизнес-логику, запросы от клиента и взаимодействует с базой данных.
|
||||
Вся верстка и фронтенд код (собранный через Webpack) размещаются в папке wwwroot или другой папке для статических файлов.
|
||||
|
||||
🎃 Автоматизация сборки и деплоя:
|
||||
|
||||
🎈 Grunt автоматически обрабатывает сборку фронтенда, выполняет задачи, такие как минификация, копирование файлов и т. д.
|
||||
Webpack поддерживает горячую замену модулей, что ускоряет процесс разработки.
|
||||
Разработка с возможностью тестирования и отладки:
|
||||
|
||||
🎈 В процессе разработки с помощью BrowserSync можно синхронизировать несколько браузеров и автоматически перезагружать страницы.
|
||||
Webpack и Grunt делают разработку более продуктивной за счет автоматизации рутинных задач.
|
Loading…
Reference in New Issue
Block a user