myio-js-library 0.1.261 → 0.1.264
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +181 -36
- package/dist/index.d.cts +10 -0
- package/dist/index.js +181 -36
- package/dist/myio-js-library.umd.js +182 -37
- package/dist/myio-js-library.umd.min.js +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -9280,6 +9280,8 @@ var EnergyRangeTooltip = {
|
|
|
9280
9280
|
var LABEL_CHAR_LIMIT = 18;
|
|
9281
9281
|
var DEFAUL_DELAY_TIME_CONNECTION_IN_MINS = 1440;
|
|
9282
9282
|
var CSS_TAG = "head-office-card-v1";
|
|
9283
|
+
var _warnedMissingEntityId = false;
|
|
9284
|
+
var _warnedMissingDelayTime = false;
|
|
9283
9285
|
function ensureCss() {
|
|
9284
9286
|
if (!document.querySelector(`style[data-myio-css="${CSS_TAG}"]`)) {
|
|
9285
9287
|
const style = document.createElement("style");
|
|
@@ -9295,13 +9297,19 @@ function normalizeParams(params) {
|
|
|
9295
9297
|
const LogHelper2 = createLogHelper(params.debugActive ?? false);
|
|
9296
9298
|
const entityObject = params.entityObject;
|
|
9297
9299
|
if (!entityObject.entityId) {
|
|
9298
|
-
|
|
9300
|
+
if (!_warnedMissingEntityId) {
|
|
9301
|
+
_warnedMissingEntityId = true;
|
|
9302
|
+
LogHelper2.warn("[CardHeadOffice] entityId is missing on some devices, generating temporary IDs");
|
|
9303
|
+
}
|
|
9299
9304
|
entityObject.entityId = `temp-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
9300
9305
|
}
|
|
9301
9306
|
if (!params.delayTimeConnectionInMins) {
|
|
9302
|
-
|
|
9303
|
-
|
|
9304
|
-
|
|
9307
|
+
if (!_warnedMissingDelayTime) {
|
|
9308
|
+
_warnedMissingDelayTime = true;
|
|
9309
|
+
LogHelper2.warn(
|
|
9310
|
+
`[CardHeadOffice] delayTimeConnectionInMins is missing, defaulting to ${DEFAUL_DELAY_TIME_CONNECTION_IN_MINS} mins`
|
|
9311
|
+
);
|
|
9312
|
+
}
|
|
9305
9313
|
}
|
|
9306
9314
|
return {
|
|
9307
9315
|
entityObject,
|
|
@@ -9792,26 +9800,10 @@ function verifyOfflineStatus(entityObject, delayTimeInMins = 15, LogHelper2) {
|
|
|
9792
9800
|
let isOffline = false;
|
|
9793
9801
|
if (lastDisconnectTime.getTime() > lastConnectionTime.getTime()) {
|
|
9794
9802
|
isOffline = true;
|
|
9795
|
-
LogHelper2.log(
|
|
9796
|
-
"[CardHeadOffice][ConnectionStatus Verify] Device is OFFLINE because lastDisconnectTime is more recent than lastConnectTime",
|
|
9797
|
-
entityObject.nameEl
|
|
9798
|
-
);
|
|
9799
9803
|
} else if (timeSinceConnection > delayTimeInMs) {
|
|
9800
9804
|
isOffline = true;
|
|
9801
|
-
LogHelper2.log(
|
|
9802
|
-
"[CardHeadOffice][ConnectionStatus Verify] Device is OFFLINE because lastConnectTime is older than configured delayTimeConnectionInMins:",
|
|
9803
|
-
delayTimeInMins,
|
|
9804
|
-
"for device",
|
|
9805
|
-
entityObject.nameEl
|
|
9806
|
-
);
|
|
9807
9805
|
} else {
|
|
9808
9806
|
isOffline = false;
|
|
9809
|
-
LogHelper2.log(
|
|
9810
|
-
"[CardHeadOffice][ConnectionStatus Verify] Device is ONLINE because lastConnectTime is within configured delayTimeConnectionInMins:",
|
|
9811
|
-
delayTimeInMins,
|
|
9812
|
-
"for device",
|
|
9813
|
-
entityObject.nameEl
|
|
9814
|
-
);
|
|
9815
9807
|
}
|
|
9816
9808
|
return isOffline;
|
|
9817
9809
|
}
|
|
@@ -9820,30 +9812,16 @@ function paint(root, state6) {
|
|
|
9820
9812
|
let statusDecisionSource = "unknown";
|
|
9821
9813
|
if (entityObject.connectionStatus) {
|
|
9822
9814
|
if (entityObject.connectionStatus === "offline") {
|
|
9823
|
-
LogHelper2.log(
|
|
9824
|
-
"[CardHeadOffice][ConnectionStatus Verify 01] Setting deviceStatus to OFFLINE based on connectionStatus"
|
|
9825
|
-
);
|
|
9826
9815
|
entityObject.deviceStatus = DeviceStatusType.OFFLINE;
|
|
9827
9816
|
statusDecisionSource = 'connectionStatus === "offline"';
|
|
9828
9817
|
} else {
|
|
9829
|
-
LogHelper2.log(
|
|
9830
|
-
"[CardHeadOffice] Device is ONLINE or WAITING based on connectionStatus for device",
|
|
9831
|
-
entityObject.nameEl
|
|
9832
|
-
);
|
|
9833
9818
|
statusDecisionSource = `connectionStatus === "${entityObject.connectionStatus}" (kept original deviceStatus)`;
|
|
9834
9819
|
}
|
|
9835
9820
|
} else {
|
|
9836
9821
|
if (verifyOfflineStatus(entityObject, delayTimeConnectionInMins, LogHelper2) === false) {
|
|
9837
|
-
LogHelper2.log(
|
|
9838
|
-
"[CardHeadOffice][ConnectionStatus Verify 02] Setting deviceStatus to OFFLINE based on timestamp verification by verifyOfflineStatus METHOD with delayTimeConnectionInMins:",
|
|
9839
|
-
delayTimeConnectionInMins
|
|
9840
|
-
);
|
|
9841
9822
|
entityObject.deviceStatus = DeviceStatusType.OFFLINE;
|
|
9842
9823
|
statusDecisionSource = `verifyOfflineStatus() returned false (delay: ${delayTimeConnectionInMins} mins)`;
|
|
9843
9824
|
} else {
|
|
9844
|
-
LogHelper2.log(
|
|
9845
|
-
`[CardHeadOffice][ConnectionStatus Verify 03] Device is ONLINE with deviceStatus = ${entityObject.deviceStatus} based on timestamp verification for device ${entityObject.nameEl}`
|
|
9846
|
-
);
|
|
9847
9825
|
statusDecisionSource = `verifyOfflineStatus() returned true (delay: ${delayTimeConnectionInMins} mins)`;
|
|
9848
9826
|
}
|
|
9849
9827
|
}
|
|
@@ -26378,9 +26356,43 @@ var WelcomeModalView = class {
|
|
|
26378
26356
|
userEmailEl.textContent = this.params.userInfo.email;
|
|
26379
26357
|
return;
|
|
26380
26358
|
}
|
|
26359
|
+
const getToken = () => {
|
|
26360
|
+
const tokenKeys = ["jwt_token", "access_token", "authToken", "tb_token"];
|
|
26361
|
+
for (const key of tokenKeys) {
|
|
26362
|
+
const token = localStorage.getItem(key);
|
|
26363
|
+
if (token) return token;
|
|
26364
|
+
}
|
|
26365
|
+
for (const key of tokenKeys) {
|
|
26366
|
+
const token = sessionStorage.getItem(key);
|
|
26367
|
+
if (token) return token;
|
|
26368
|
+
}
|
|
26369
|
+
const win = window;
|
|
26370
|
+
if (win.AuthService?.jwtToken) return win.AuthService.jwtToken;
|
|
26371
|
+
const cookies = document.cookie.split(";");
|
|
26372
|
+
for (const cookie of cookies) {
|
|
26373
|
+
const [name, value] = cookie.trim().split("=");
|
|
26374
|
+
if (tokenKeys.includes(name)) return value;
|
|
26375
|
+
}
|
|
26376
|
+
return null;
|
|
26377
|
+
};
|
|
26381
26378
|
try {
|
|
26382
|
-
const token =
|
|
26379
|
+
const token = getToken();
|
|
26383
26380
|
if (!token) {
|
|
26381
|
+
const ctx = this.params.ctx;
|
|
26382
|
+
if (ctx?.currentUser) {
|
|
26383
|
+
const user = ctx.currentUser;
|
|
26384
|
+
const fullName = [user.firstName, user.lastName].filter(Boolean).join(" ") || user.name || "Usu\xE1rio";
|
|
26385
|
+
userNameEl.textContent = fullName;
|
|
26386
|
+
userEmailEl.textContent = user.email || "";
|
|
26387
|
+
return;
|
|
26388
|
+
}
|
|
26389
|
+
const tbUser = window.tb_user;
|
|
26390
|
+
if (tbUser) {
|
|
26391
|
+
const fullName = [tbUser.firstName, tbUser.lastName].filter(Boolean).join(" ") || tbUser.name || "Usu\xE1rio";
|
|
26392
|
+
userNameEl.textContent = fullName;
|
|
26393
|
+
userEmailEl.textContent = tbUser.email || "";
|
|
26394
|
+
return;
|
|
26395
|
+
}
|
|
26384
26396
|
userNameEl.textContent = "Usu\xE1rio";
|
|
26385
26397
|
userEmailEl.textContent = "";
|
|
26386
26398
|
return;
|
|
@@ -26414,6 +26426,124 @@ var WelcomeModalView = class {
|
|
|
26414
26426
|
if (userNameEl) userNameEl.textContent = info.fullName;
|
|
26415
26427
|
if (userEmailEl) userEmailEl.textContent = info.email;
|
|
26416
26428
|
}
|
|
26429
|
+
/**
|
|
26430
|
+
* Update shopping cards after data loads (RFC-0111: loading state support)
|
|
26431
|
+
*/
|
|
26432
|
+
updateShoppingCards(cards) {
|
|
26433
|
+
this.params.shoppingCards = cards;
|
|
26434
|
+
let shortcutsSection = this.container.querySelector(".myio-welcome-shortcuts");
|
|
26435
|
+
const modalContainer = this.container.querySelector(".myio-welcome-modal-container");
|
|
26436
|
+
if (cards.length === 0) {
|
|
26437
|
+
if (shortcutsSection) {
|
|
26438
|
+
shortcutsSection.remove();
|
|
26439
|
+
}
|
|
26440
|
+
return;
|
|
26441
|
+
}
|
|
26442
|
+
const shortcutsTitle = this.params.shortcutsTitle ?? this.config.defaultShortcutsTitle ?? "Acesso R\xE1pido aos Shoppings";
|
|
26443
|
+
const themeConfig = this.getThemeConfig();
|
|
26444
|
+
const shortcutsTitleColor = themeConfig.shortcutsTitleColor ?? themeConfig.mutedTextColor;
|
|
26445
|
+
if (!shortcutsSection && modalContainer) {
|
|
26446
|
+
shortcutsSection = document.createElement("div");
|
|
26447
|
+
shortcutsSection.className = "myio-welcome-shortcuts";
|
|
26448
|
+
modalContainer.appendChild(shortcutsSection);
|
|
26449
|
+
}
|
|
26450
|
+
if (shortcutsSection) {
|
|
26451
|
+
shortcutsSection.innerHTML = `
|
|
26452
|
+
<h2 class="myio-welcome-shortcuts-title"${shortcutsTitleColor ? ` style="color: ${shortcutsTitleColor}"` : ""}>${shortcutsTitle}</h2>
|
|
26453
|
+
<div class="myio-welcome-cards-grid" id="welcomeCardsGrid">
|
|
26454
|
+
${cards.map((card, index) => this.buildCardHTML(card, index)).join("")}
|
|
26455
|
+
</div>
|
|
26456
|
+
`;
|
|
26457
|
+
this.bindCardEvents();
|
|
26458
|
+
this.setupLazyLoading();
|
|
26459
|
+
}
|
|
26460
|
+
if (this.config.enableDebugMode) {
|
|
26461
|
+
console.log("[WelcomeModal] Shopping cards updated:", cards.length);
|
|
26462
|
+
}
|
|
26463
|
+
}
|
|
26464
|
+
/**
|
|
26465
|
+
* Bind events for shopping cards (used after dynamic update)
|
|
26466
|
+
*/
|
|
26467
|
+
bindCardEvents() {
|
|
26468
|
+
const cards = this.container.querySelectorAll(".myio-welcome-card");
|
|
26469
|
+
cards.forEach((card, index) => {
|
|
26470
|
+
const shoppingCard = this.params.shoppingCards?.[index];
|
|
26471
|
+
if (!shoppingCard) return;
|
|
26472
|
+
card.addEventListener("click", (e) => {
|
|
26473
|
+
const target = e.target;
|
|
26474
|
+
if (target.closest(".myio-welcome-card-device-count")) {
|
|
26475
|
+
return;
|
|
26476
|
+
}
|
|
26477
|
+
this.emit("card-click", shoppingCard);
|
|
26478
|
+
});
|
|
26479
|
+
card.addEventListener("keydown", (e) => {
|
|
26480
|
+
const keyEvent = e;
|
|
26481
|
+
if (keyEvent.key === "Enter" || keyEvent.key === " ") {
|
|
26482
|
+
e.preventDefault();
|
|
26483
|
+
this.emit("card-click", shoppingCard);
|
|
26484
|
+
}
|
|
26485
|
+
});
|
|
26486
|
+
});
|
|
26487
|
+
this.bindTooltipEvents();
|
|
26488
|
+
}
|
|
26489
|
+
/**
|
|
26490
|
+
* Set CTA button label
|
|
26491
|
+
*/
|
|
26492
|
+
setCtaLabel(label) {
|
|
26493
|
+
const ctaBtn = this.container.querySelector("#welcomeCtaBtn");
|
|
26494
|
+
if (ctaBtn) {
|
|
26495
|
+
const svgIcon = ctaBtn.querySelector("svg");
|
|
26496
|
+
ctaBtn.textContent = "";
|
|
26497
|
+
ctaBtn.appendChild(document.createTextNode(label + " "));
|
|
26498
|
+
if (svgIcon) {
|
|
26499
|
+
ctaBtn.appendChild(svgIcon);
|
|
26500
|
+
} else {
|
|
26501
|
+
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
26502
|
+
svg.setAttribute("viewBox", "0 0 24 24");
|
|
26503
|
+
svg.setAttribute("fill", "none");
|
|
26504
|
+
svg.setAttribute("stroke", "currentColor");
|
|
26505
|
+
svg.setAttribute("stroke-width", "2");
|
|
26506
|
+
svg.setAttribute("stroke-linecap", "round");
|
|
26507
|
+
svg.setAttribute("stroke-linejoin", "round");
|
|
26508
|
+
svg.innerHTML = '<line x1="5" y1="12" x2="19" y2="12" /><polyline points="12 5 19 12 12 19" />';
|
|
26509
|
+
ctaBtn.appendChild(svg);
|
|
26510
|
+
}
|
|
26511
|
+
}
|
|
26512
|
+
}
|
|
26513
|
+
/**
|
|
26514
|
+
* Set CTA button disabled state
|
|
26515
|
+
*/
|
|
26516
|
+
setCtaDisabled(disabled) {
|
|
26517
|
+
const ctaBtn = this.container.querySelector("#welcomeCtaBtn");
|
|
26518
|
+
if (ctaBtn) {
|
|
26519
|
+
ctaBtn.disabled = disabled;
|
|
26520
|
+
ctaBtn.style.opacity = disabled ? "0.5" : "1";
|
|
26521
|
+
ctaBtn.style.cursor = disabled ? "not-allowed" : "pointer";
|
|
26522
|
+
}
|
|
26523
|
+
}
|
|
26524
|
+
/**
|
|
26525
|
+
* Show the modal (after it was hidden)
|
|
26526
|
+
*/
|
|
26527
|
+
show() {
|
|
26528
|
+
this.container.style.display = "flex";
|
|
26529
|
+
this.container.style.opacity = "0";
|
|
26530
|
+
requestAnimationFrame(() => {
|
|
26531
|
+
this.container.style.opacity = "1";
|
|
26532
|
+
this.container.style.transition = "opacity 0.3s ease";
|
|
26533
|
+
});
|
|
26534
|
+
document.body.style.overflow = "hidden";
|
|
26535
|
+
}
|
|
26536
|
+
/**
|
|
26537
|
+
* Hide the modal (without destroying it)
|
|
26538
|
+
*/
|
|
26539
|
+
hide() {
|
|
26540
|
+
this.container.style.opacity = "0";
|
|
26541
|
+
this.container.style.transition = "opacity 0.3s ease";
|
|
26542
|
+
setTimeout(() => {
|
|
26543
|
+
this.container.style.display = "none";
|
|
26544
|
+
document.body.style.overflow = "";
|
|
26545
|
+
}, 300);
|
|
26546
|
+
}
|
|
26417
26547
|
/**
|
|
26418
26548
|
* Cleanup resources
|
|
26419
26549
|
*/
|
|
@@ -26534,8 +26664,15 @@ function openWelcomeModal(params) {
|
|
|
26534
26664
|
element.style.opacity = "1";
|
|
26535
26665
|
element.style.transition = "opacity 0.3s ease";
|
|
26536
26666
|
});
|
|
26667
|
+
function open() {
|
|
26668
|
+
if (!element.parentNode) {
|
|
26669
|
+
document.body.appendChild(element);
|
|
26670
|
+
}
|
|
26671
|
+
view.show();
|
|
26672
|
+
}
|
|
26537
26673
|
return {
|
|
26538
26674
|
close,
|
|
26675
|
+
open,
|
|
26539
26676
|
element,
|
|
26540
26677
|
on: (event, handler) => {
|
|
26541
26678
|
if (event === "close") {
|
|
@@ -26545,7 +26682,15 @@ function openWelcomeModal(params) {
|
|
|
26545
26682
|
/** Set the theme mode from outside (e.g., from MAIN component) */
|
|
26546
26683
|
setThemeMode: (mode) => view.setThemeMode(mode),
|
|
26547
26684
|
/** Get the current theme mode */
|
|
26548
|
-
getThemeMode: () => view.getThemeMode()
|
|
26685
|
+
getThemeMode: () => view.getThemeMode(),
|
|
26686
|
+
/** Update shopping cards after data loads (RFC-0111: loading state) */
|
|
26687
|
+
updateShoppingCards: (cards) => view.updateShoppingCards(cards),
|
|
26688
|
+
/** Update user info display */
|
|
26689
|
+
updateUserInfo: (info) => view.updateUserInfo(info),
|
|
26690
|
+
/** Set CTA button label */
|
|
26691
|
+
setCtaLabel: (label) => view.setCtaLabel(label),
|
|
26692
|
+
/** Set CTA button disabled state */
|
|
26693
|
+
setCtaDisabled: (disabled) => view.setCtaDisabled(disabled)
|
|
26549
26694
|
};
|
|
26550
26695
|
}
|
|
26551
26696
|
|
package/dist/index.d.cts
CHANGED
|
@@ -2788,6 +2788,8 @@ interface WelcomeModalParams {
|
|
|
2788
2788
|
interface WelcomeModalInstance {
|
|
2789
2789
|
/** Close the modal programmatically */
|
|
2790
2790
|
close: () => void;
|
|
2791
|
+
/** Open/show the modal again after it was closed */
|
|
2792
|
+
open: () => void;
|
|
2791
2793
|
/** The modal's root DOM element */
|
|
2792
2794
|
element: HTMLElement;
|
|
2793
2795
|
/** Register event handlers */
|
|
@@ -2796,6 +2798,14 @@ interface WelcomeModalInstance {
|
|
|
2796
2798
|
setThemeMode: (mode: WelcomeThemeMode) => void;
|
|
2797
2799
|
/** Get the current theme mode */
|
|
2798
2800
|
getThemeMode: () => WelcomeThemeMode;
|
|
2801
|
+
/** Update shopping cards after data loads (RFC-0111: loading state) */
|
|
2802
|
+
updateShoppingCards: (cards: ShoppingCard[]) => void;
|
|
2803
|
+
/** Update user info display */
|
|
2804
|
+
updateUserInfo: (info: UserInfo$1) => void;
|
|
2805
|
+
/** Set CTA button label */
|
|
2806
|
+
setCtaLabel: (label: string) => void;
|
|
2807
|
+
/** Set CTA button disabled state */
|
|
2808
|
+
setCtaDisabled: (disabled: boolean) => void;
|
|
2799
2809
|
}
|
|
2800
2810
|
/**
|
|
2801
2811
|
* Default palette values
|
package/dist/index.js
CHANGED
|
@@ -9063,6 +9063,8 @@ var EnergyRangeTooltip = {
|
|
|
9063
9063
|
var LABEL_CHAR_LIMIT = 18;
|
|
9064
9064
|
var DEFAUL_DELAY_TIME_CONNECTION_IN_MINS = 1440;
|
|
9065
9065
|
var CSS_TAG = "head-office-card-v1";
|
|
9066
|
+
var _warnedMissingEntityId = false;
|
|
9067
|
+
var _warnedMissingDelayTime = false;
|
|
9066
9068
|
function ensureCss() {
|
|
9067
9069
|
if (!document.querySelector(`style[data-myio-css="${CSS_TAG}"]`)) {
|
|
9068
9070
|
const style = document.createElement("style");
|
|
@@ -9078,13 +9080,19 @@ function normalizeParams(params) {
|
|
|
9078
9080
|
const LogHelper2 = createLogHelper(params.debugActive ?? false);
|
|
9079
9081
|
const entityObject = params.entityObject;
|
|
9080
9082
|
if (!entityObject.entityId) {
|
|
9081
|
-
|
|
9083
|
+
if (!_warnedMissingEntityId) {
|
|
9084
|
+
_warnedMissingEntityId = true;
|
|
9085
|
+
LogHelper2.warn("[CardHeadOffice] entityId is missing on some devices, generating temporary IDs");
|
|
9086
|
+
}
|
|
9082
9087
|
entityObject.entityId = `temp-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
9083
9088
|
}
|
|
9084
9089
|
if (!params.delayTimeConnectionInMins) {
|
|
9085
|
-
|
|
9086
|
-
|
|
9087
|
-
|
|
9090
|
+
if (!_warnedMissingDelayTime) {
|
|
9091
|
+
_warnedMissingDelayTime = true;
|
|
9092
|
+
LogHelper2.warn(
|
|
9093
|
+
`[CardHeadOffice] delayTimeConnectionInMins is missing, defaulting to ${DEFAUL_DELAY_TIME_CONNECTION_IN_MINS} mins`
|
|
9094
|
+
);
|
|
9095
|
+
}
|
|
9088
9096
|
}
|
|
9089
9097
|
return {
|
|
9090
9098
|
entityObject,
|
|
@@ -9575,26 +9583,10 @@ function verifyOfflineStatus(entityObject, delayTimeInMins = 15, LogHelper2) {
|
|
|
9575
9583
|
let isOffline = false;
|
|
9576
9584
|
if (lastDisconnectTime.getTime() > lastConnectionTime.getTime()) {
|
|
9577
9585
|
isOffline = true;
|
|
9578
|
-
LogHelper2.log(
|
|
9579
|
-
"[CardHeadOffice][ConnectionStatus Verify] Device is OFFLINE because lastDisconnectTime is more recent than lastConnectTime",
|
|
9580
|
-
entityObject.nameEl
|
|
9581
|
-
);
|
|
9582
9586
|
} else if (timeSinceConnection > delayTimeInMs) {
|
|
9583
9587
|
isOffline = true;
|
|
9584
|
-
LogHelper2.log(
|
|
9585
|
-
"[CardHeadOffice][ConnectionStatus Verify] Device is OFFLINE because lastConnectTime is older than configured delayTimeConnectionInMins:",
|
|
9586
|
-
delayTimeInMins,
|
|
9587
|
-
"for device",
|
|
9588
|
-
entityObject.nameEl
|
|
9589
|
-
);
|
|
9590
9588
|
} else {
|
|
9591
9589
|
isOffline = false;
|
|
9592
|
-
LogHelper2.log(
|
|
9593
|
-
"[CardHeadOffice][ConnectionStatus Verify] Device is ONLINE because lastConnectTime is within configured delayTimeConnectionInMins:",
|
|
9594
|
-
delayTimeInMins,
|
|
9595
|
-
"for device",
|
|
9596
|
-
entityObject.nameEl
|
|
9597
|
-
);
|
|
9598
9590
|
}
|
|
9599
9591
|
return isOffline;
|
|
9600
9592
|
}
|
|
@@ -9603,30 +9595,16 @@ function paint(root, state6) {
|
|
|
9603
9595
|
let statusDecisionSource = "unknown";
|
|
9604
9596
|
if (entityObject.connectionStatus) {
|
|
9605
9597
|
if (entityObject.connectionStatus === "offline") {
|
|
9606
|
-
LogHelper2.log(
|
|
9607
|
-
"[CardHeadOffice][ConnectionStatus Verify 01] Setting deviceStatus to OFFLINE based on connectionStatus"
|
|
9608
|
-
);
|
|
9609
9598
|
entityObject.deviceStatus = DeviceStatusType.OFFLINE;
|
|
9610
9599
|
statusDecisionSource = 'connectionStatus === "offline"';
|
|
9611
9600
|
} else {
|
|
9612
|
-
LogHelper2.log(
|
|
9613
|
-
"[CardHeadOffice] Device is ONLINE or WAITING based on connectionStatus for device",
|
|
9614
|
-
entityObject.nameEl
|
|
9615
|
-
);
|
|
9616
9601
|
statusDecisionSource = `connectionStatus === "${entityObject.connectionStatus}" (kept original deviceStatus)`;
|
|
9617
9602
|
}
|
|
9618
9603
|
} else {
|
|
9619
9604
|
if (verifyOfflineStatus(entityObject, delayTimeConnectionInMins, LogHelper2) === false) {
|
|
9620
|
-
LogHelper2.log(
|
|
9621
|
-
"[CardHeadOffice][ConnectionStatus Verify 02] Setting deviceStatus to OFFLINE based on timestamp verification by verifyOfflineStatus METHOD with delayTimeConnectionInMins:",
|
|
9622
|
-
delayTimeConnectionInMins
|
|
9623
|
-
);
|
|
9624
9605
|
entityObject.deviceStatus = DeviceStatusType.OFFLINE;
|
|
9625
9606
|
statusDecisionSource = `verifyOfflineStatus() returned false (delay: ${delayTimeConnectionInMins} mins)`;
|
|
9626
9607
|
} else {
|
|
9627
|
-
LogHelper2.log(
|
|
9628
|
-
`[CardHeadOffice][ConnectionStatus Verify 03] Device is ONLINE with deviceStatus = ${entityObject.deviceStatus} based on timestamp verification for device ${entityObject.nameEl}`
|
|
9629
|
-
);
|
|
9630
9608
|
statusDecisionSource = `verifyOfflineStatus() returned true (delay: ${delayTimeConnectionInMins} mins)`;
|
|
9631
9609
|
}
|
|
9632
9610
|
}
|
|
@@ -26161,9 +26139,43 @@ var WelcomeModalView = class {
|
|
|
26161
26139
|
userEmailEl.textContent = this.params.userInfo.email;
|
|
26162
26140
|
return;
|
|
26163
26141
|
}
|
|
26142
|
+
const getToken = () => {
|
|
26143
|
+
const tokenKeys = ["jwt_token", "access_token", "authToken", "tb_token"];
|
|
26144
|
+
for (const key of tokenKeys) {
|
|
26145
|
+
const token = localStorage.getItem(key);
|
|
26146
|
+
if (token) return token;
|
|
26147
|
+
}
|
|
26148
|
+
for (const key of tokenKeys) {
|
|
26149
|
+
const token = sessionStorage.getItem(key);
|
|
26150
|
+
if (token) return token;
|
|
26151
|
+
}
|
|
26152
|
+
const win = window;
|
|
26153
|
+
if (win.AuthService?.jwtToken) return win.AuthService.jwtToken;
|
|
26154
|
+
const cookies = document.cookie.split(";");
|
|
26155
|
+
for (const cookie of cookies) {
|
|
26156
|
+
const [name, value] = cookie.trim().split("=");
|
|
26157
|
+
if (tokenKeys.includes(name)) return value;
|
|
26158
|
+
}
|
|
26159
|
+
return null;
|
|
26160
|
+
};
|
|
26164
26161
|
try {
|
|
26165
|
-
const token =
|
|
26162
|
+
const token = getToken();
|
|
26166
26163
|
if (!token) {
|
|
26164
|
+
const ctx = this.params.ctx;
|
|
26165
|
+
if (ctx?.currentUser) {
|
|
26166
|
+
const user = ctx.currentUser;
|
|
26167
|
+
const fullName = [user.firstName, user.lastName].filter(Boolean).join(" ") || user.name || "Usu\xE1rio";
|
|
26168
|
+
userNameEl.textContent = fullName;
|
|
26169
|
+
userEmailEl.textContent = user.email || "";
|
|
26170
|
+
return;
|
|
26171
|
+
}
|
|
26172
|
+
const tbUser = window.tb_user;
|
|
26173
|
+
if (tbUser) {
|
|
26174
|
+
const fullName = [tbUser.firstName, tbUser.lastName].filter(Boolean).join(" ") || tbUser.name || "Usu\xE1rio";
|
|
26175
|
+
userNameEl.textContent = fullName;
|
|
26176
|
+
userEmailEl.textContent = tbUser.email || "";
|
|
26177
|
+
return;
|
|
26178
|
+
}
|
|
26167
26179
|
userNameEl.textContent = "Usu\xE1rio";
|
|
26168
26180
|
userEmailEl.textContent = "";
|
|
26169
26181
|
return;
|
|
@@ -26197,6 +26209,124 @@ var WelcomeModalView = class {
|
|
|
26197
26209
|
if (userNameEl) userNameEl.textContent = info.fullName;
|
|
26198
26210
|
if (userEmailEl) userEmailEl.textContent = info.email;
|
|
26199
26211
|
}
|
|
26212
|
+
/**
|
|
26213
|
+
* Update shopping cards after data loads (RFC-0111: loading state support)
|
|
26214
|
+
*/
|
|
26215
|
+
updateShoppingCards(cards) {
|
|
26216
|
+
this.params.shoppingCards = cards;
|
|
26217
|
+
let shortcutsSection = this.container.querySelector(".myio-welcome-shortcuts");
|
|
26218
|
+
const modalContainer = this.container.querySelector(".myio-welcome-modal-container");
|
|
26219
|
+
if (cards.length === 0) {
|
|
26220
|
+
if (shortcutsSection) {
|
|
26221
|
+
shortcutsSection.remove();
|
|
26222
|
+
}
|
|
26223
|
+
return;
|
|
26224
|
+
}
|
|
26225
|
+
const shortcutsTitle = this.params.shortcutsTitle ?? this.config.defaultShortcutsTitle ?? "Acesso R\xE1pido aos Shoppings";
|
|
26226
|
+
const themeConfig = this.getThemeConfig();
|
|
26227
|
+
const shortcutsTitleColor = themeConfig.shortcutsTitleColor ?? themeConfig.mutedTextColor;
|
|
26228
|
+
if (!shortcutsSection && modalContainer) {
|
|
26229
|
+
shortcutsSection = document.createElement("div");
|
|
26230
|
+
shortcutsSection.className = "myio-welcome-shortcuts";
|
|
26231
|
+
modalContainer.appendChild(shortcutsSection);
|
|
26232
|
+
}
|
|
26233
|
+
if (shortcutsSection) {
|
|
26234
|
+
shortcutsSection.innerHTML = `
|
|
26235
|
+
<h2 class="myio-welcome-shortcuts-title"${shortcutsTitleColor ? ` style="color: ${shortcutsTitleColor}"` : ""}>${shortcutsTitle}</h2>
|
|
26236
|
+
<div class="myio-welcome-cards-grid" id="welcomeCardsGrid">
|
|
26237
|
+
${cards.map((card, index) => this.buildCardHTML(card, index)).join("")}
|
|
26238
|
+
</div>
|
|
26239
|
+
`;
|
|
26240
|
+
this.bindCardEvents();
|
|
26241
|
+
this.setupLazyLoading();
|
|
26242
|
+
}
|
|
26243
|
+
if (this.config.enableDebugMode) {
|
|
26244
|
+
console.log("[WelcomeModal] Shopping cards updated:", cards.length);
|
|
26245
|
+
}
|
|
26246
|
+
}
|
|
26247
|
+
/**
|
|
26248
|
+
* Bind events for shopping cards (used after dynamic update)
|
|
26249
|
+
*/
|
|
26250
|
+
bindCardEvents() {
|
|
26251
|
+
const cards = this.container.querySelectorAll(".myio-welcome-card");
|
|
26252
|
+
cards.forEach((card, index) => {
|
|
26253
|
+
const shoppingCard = this.params.shoppingCards?.[index];
|
|
26254
|
+
if (!shoppingCard) return;
|
|
26255
|
+
card.addEventListener("click", (e) => {
|
|
26256
|
+
const target = e.target;
|
|
26257
|
+
if (target.closest(".myio-welcome-card-device-count")) {
|
|
26258
|
+
return;
|
|
26259
|
+
}
|
|
26260
|
+
this.emit("card-click", shoppingCard);
|
|
26261
|
+
});
|
|
26262
|
+
card.addEventListener("keydown", (e) => {
|
|
26263
|
+
const keyEvent = e;
|
|
26264
|
+
if (keyEvent.key === "Enter" || keyEvent.key === " ") {
|
|
26265
|
+
e.preventDefault();
|
|
26266
|
+
this.emit("card-click", shoppingCard);
|
|
26267
|
+
}
|
|
26268
|
+
});
|
|
26269
|
+
});
|
|
26270
|
+
this.bindTooltipEvents();
|
|
26271
|
+
}
|
|
26272
|
+
/**
|
|
26273
|
+
* Set CTA button label
|
|
26274
|
+
*/
|
|
26275
|
+
setCtaLabel(label) {
|
|
26276
|
+
const ctaBtn = this.container.querySelector("#welcomeCtaBtn");
|
|
26277
|
+
if (ctaBtn) {
|
|
26278
|
+
const svgIcon = ctaBtn.querySelector("svg");
|
|
26279
|
+
ctaBtn.textContent = "";
|
|
26280
|
+
ctaBtn.appendChild(document.createTextNode(label + " "));
|
|
26281
|
+
if (svgIcon) {
|
|
26282
|
+
ctaBtn.appendChild(svgIcon);
|
|
26283
|
+
} else {
|
|
26284
|
+
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
26285
|
+
svg.setAttribute("viewBox", "0 0 24 24");
|
|
26286
|
+
svg.setAttribute("fill", "none");
|
|
26287
|
+
svg.setAttribute("stroke", "currentColor");
|
|
26288
|
+
svg.setAttribute("stroke-width", "2");
|
|
26289
|
+
svg.setAttribute("stroke-linecap", "round");
|
|
26290
|
+
svg.setAttribute("stroke-linejoin", "round");
|
|
26291
|
+
svg.innerHTML = '<line x1="5" y1="12" x2="19" y2="12" /><polyline points="12 5 19 12 12 19" />';
|
|
26292
|
+
ctaBtn.appendChild(svg);
|
|
26293
|
+
}
|
|
26294
|
+
}
|
|
26295
|
+
}
|
|
26296
|
+
/**
|
|
26297
|
+
* Set CTA button disabled state
|
|
26298
|
+
*/
|
|
26299
|
+
setCtaDisabled(disabled) {
|
|
26300
|
+
const ctaBtn = this.container.querySelector("#welcomeCtaBtn");
|
|
26301
|
+
if (ctaBtn) {
|
|
26302
|
+
ctaBtn.disabled = disabled;
|
|
26303
|
+
ctaBtn.style.opacity = disabled ? "0.5" : "1";
|
|
26304
|
+
ctaBtn.style.cursor = disabled ? "not-allowed" : "pointer";
|
|
26305
|
+
}
|
|
26306
|
+
}
|
|
26307
|
+
/**
|
|
26308
|
+
* Show the modal (after it was hidden)
|
|
26309
|
+
*/
|
|
26310
|
+
show() {
|
|
26311
|
+
this.container.style.display = "flex";
|
|
26312
|
+
this.container.style.opacity = "0";
|
|
26313
|
+
requestAnimationFrame(() => {
|
|
26314
|
+
this.container.style.opacity = "1";
|
|
26315
|
+
this.container.style.transition = "opacity 0.3s ease";
|
|
26316
|
+
});
|
|
26317
|
+
document.body.style.overflow = "hidden";
|
|
26318
|
+
}
|
|
26319
|
+
/**
|
|
26320
|
+
* Hide the modal (without destroying it)
|
|
26321
|
+
*/
|
|
26322
|
+
hide() {
|
|
26323
|
+
this.container.style.opacity = "0";
|
|
26324
|
+
this.container.style.transition = "opacity 0.3s ease";
|
|
26325
|
+
setTimeout(() => {
|
|
26326
|
+
this.container.style.display = "none";
|
|
26327
|
+
document.body.style.overflow = "";
|
|
26328
|
+
}, 300);
|
|
26329
|
+
}
|
|
26200
26330
|
/**
|
|
26201
26331
|
* Cleanup resources
|
|
26202
26332
|
*/
|
|
@@ -26317,8 +26447,15 @@ function openWelcomeModal(params) {
|
|
|
26317
26447
|
element.style.opacity = "1";
|
|
26318
26448
|
element.style.transition = "opacity 0.3s ease";
|
|
26319
26449
|
});
|
|
26450
|
+
function open() {
|
|
26451
|
+
if (!element.parentNode) {
|
|
26452
|
+
document.body.appendChild(element);
|
|
26453
|
+
}
|
|
26454
|
+
view.show();
|
|
26455
|
+
}
|
|
26320
26456
|
return {
|
|
26321
26457
|
close,
|
|
26458
|
+
open,
|
|
26322
26459
|
element,
|
|
26323
26460
|
on: (event, handler) => {
|
|
26324
26461
|
if (event === "close") {
|
|
@@ -26328,7 +26465,15 @@ function openWelcomeModal(params) {
|
|
|
26328
26465
|
/** Set the theme mode from outside (e.g., from MAIN component) */
|
|
26329
26466
|
setThemeMode: (mode) => view.setThemeMode(mode),
|
|
26330
26467
|
/** Get the current theme mode */
|
|
26331
|
-
getThemeMode: () => view.getThemeMode()
|
|
26468
|
+
getThemeMode: () => view.getThemeMode(),
|
|
26469
|
+
/** Update shopping cards after data loads (RFC-0111: loading state) */
|
|
26470
|
+
updateShoppingCards: (cards) => view.updateShoppingCards(cards),
|
|
26471
|
+
/** Update user info display */
|
|
26472
|
+
updateUserInfo: (info) => view.updateUserInfo(info),
|
|
26473
|
+
/** Set CTA button label */
|
|
26474
|
+
setCtaLabel: (label) => view.setCtaLabel(label),
|
|
26475
|
+
/** Set CTA button disabled state */
|
|
26476
|
+
setCtaDisabled: (disabled) => view.setCtaDisabled(disabled)
|
|
26332
26477
|
};
|
|
26333
26478
|
}
|
|
26334
26479
|
|