Files
yangsh 735120f1cb
Some checks failed
Close Pull Request / main (pull_request_target) Has been cancelled
new
2025-12-09 17:28:31 +09:00

371 lines
12 KiB
JavaScript

// Imports
import $ from "jquery";
window.jQuery = $;
window.$ = $;
import * as bootstrap from 'bootstrap';
import { Dropdown } from 'bootstrap';
import "metismenu";
// Stylesheets
import "./assets/base.scss";
// Import fixed timing loader (simpler, more reliable)
// Temporarily disabled to debug webpack error
// import "./utils/fixed-loader.js";
$(document).ready(() => {
// Page Transition Animations
function initPageAnimations() {
// SimpleLoader handles the loader, we just need to trigger animations
// Wait a bit to ensure loader has been handled
setTimeout(() => {
// Trigger header animation
$('.HeaderAnimation-appear').addClass('HeaderAnimation-appear-active');
// Trigger main content animation with slight delay
setTimeout(() => {
$('.MainAnimation-appear').addClass('MainAnimation-appear-active');
}, 100);
// Trigger sidebar animation if present
setTimeout(() => {
$('.SidebarAnimation-appear').addClass('SidebarAnimation-appear-active');
}, 200);
// Trigger tab animations for content with tabs
setTimeout(() => {
$('.tabs-animation, .TabsAnimation-appear').addClass('TabsAnimation-appear-active');
}, 300);
}, 200);
}
// Initialize animations when body has app-loaded class
const waitForLoaded = () => {
if (document.body.classList.contains('app-loaded')) {
initPageAnimations();
} else {
setTimeout(waitForLoaded, 50);
}
};
waitForLoaded();
// Handle dynamic content loading transitions
function fadeInContent(selector, delay = 0) {
setTimeout(() => {
$(selector).addClass('animated fadeInUp');
}, delay);
}
// Sidebar Menu
setTimeout(function () {
$(".vertical-nav-menu").metisMenu();
// Ensure Perfect Scrollbar updates after MetisMenu initialization
setTimeout(() => {
if (window.sidebarScrollbar && window.sidebarScrollbar.update) {
window.sidebarScrollbar.update();
}
}, 50);
}, 100);
// Search wrapper trigger
$(".search-icon").click(function () {
$(this).parent().parent().addClass("active");
});
$(".search-wrapper .btn-close").click(function () {
$(this).parent().removeClass("active");
});
// BS5 Popover
var popoverTriggerList1 = [].slice.call(document.querySelectorAll('[data-bs-toggle="popover-custom-content"]'));
var popoverList = popoverTriggerList1.map(function (popoverTriggerEl1) {
return new bootstrap.Popover(popoverTriggerEl1,
{
html: true,
placement: "auto",
template:
'<div class="popover popover-custom" role="tooltip"><div class="arrow"></div><h3 class="popover-header"></h3><div class="popover-body"></div></div>',
content: function () {
var id = $(this).attr("popover-id");
return $("#popover-content-" + id).html();
},
});
});
// REMOVED: Conflicting jQuery dropdown click handler that was preventing dropdowns from opening
var popoverTriggerList2 = [].slice.call(document.querySelectorAll('[data-bs-toggle="popover-custom-bg"]'));
var popoverList = $('[data-bs-toggle="popover-custom-bg"]').each(function (popoverTriggerEl2) {
var popClass = $(this).attr('data-bg-class');
return new bootstrap.Popover($(this), {
trigger: "focus",
placement: "top",
template:
'<div class="popover popover-bg ' +
popClass +
'" role="tooltip"><h3 class="popover-header"></h3><div class="popover-body"></div></div>',
});
});
// BS5 Popover
var popoverTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="popover"]'));
var popoverList = popoverTriggerList.map(function (popoverTriggerEl) {
return new bootstrap.Popover(popoverTriggerEl);
});
$('[data-bs-toggle="popover-custom"]').each(function (i, obj) {
return new bootstrap.Popover($(this), {
html: true,
container: $(this).parent().find(".rm-max-width"),
content: function () {
return $(this)
.next(".rm-max-width")
.find(".popover-custom-content")
.html();
},
});
});
// Portal dropdown implementation - moves menus to body to escape containers
document.addEventListener('click', function(event) {
var trigger = event.target.closest('[data-bs-toggle="dropdown"]');
if (trigger) {
event.preventDefault();
event.stopPropagation();
// Close all other dropdowns first
document.querySelectorAll('.dropdown-menu.show').forEach(function(menu) {
menu.classList.remove('show');
// Restore to original position if it was portaled
if (menu._originalParent) {
if (menu._originalNextSibling) {
menu._originalParent.insertBefore(menu, menu._originalNextSibling);
} else {
menu._originalParent.appendChild(menu);
}
// Clear portal data
delete menu._originalParent;
delete menu._originalNextSibling;
// Reset styles
menu.style.position = '';
menu.style.top = '';
menu.style.left = '';
menu.style.zIndex = '';
menu.style.transform = '';
}
var toggle = document.querySelector('[data-bs-toggle="dropdown"][aria-expanded="true"]');
if (toggle) toggle.setAttribute('aria-expanded', 'false');
});
// Find the dropdown menu for this trigger
var menu = trigger.nextElementSibling;
if (!menu || !menu.classList.contains('dropdown-menu')) {
menu = trigger.parentNode.querySelector('.dropdown-menu');
}
if (menu) {
// Check if this is a header dropdown (skip portal for header dropdowns)
var isHeaderDropdown = trigger.closest('.app-header, .header-megamenu, .header-dots, .header-btn-lg');
if (isHeaderDropdown) {
// Simple show for header dropdowns (don't portal them)
menu.classList.add('show');
trigger.setAttribute('aria-expanded', 'true');
} else {
// Portal approach for page dropdowns only
var triggerRect = trigger.getBoundingClientRect();
// Store original parent and position info
if (!menu._originalParent) {
menu._originalParent = menu.parentNode;
menu._originalNextSibling = menu.nextSibling;
}
// Move to body
document.body.appendChild(menu);
// Position relative to viewport
menu.style.position = 'fixed';
menu.style.top = (triggerRect.bottom + 2) + 'px';
menu.style.left = triggerRect.left + 'px';
menu.style.zIndex = '99999';
menu.style.transform = 'none';
// Show the menu
menu.classList.add('show');
trigger.setAttribute('aria-expanded', 'true');
}
}
} else {
// Click outside - close all dropdowns
document.querySelectorAll('.dropdown-menu.show').forEach(function(menu) {
menu.classList.remove('show');
// Restore to original position if it was portaled
if (menu._originalParent) {
if (menu._originalNextSibling) {
menu._originalParent.insertBefore(menu, menu._originalNextSibling);
} else {
menu._originalParent.appendChild(menu);
}
// Clear portal data
delete menu._originalParent;
delete menu._originalNextSibling;
// Reset styles
menu.style.position = '';
menu.style.top = '';
menu.style.left = '';
menu.style.zIndex = '';
menu.style.transform = '';
}
var toggle = document.querySelector('[data-bs-toggle="dropdown"][aria-expanded="true"]');
if (toggle) toggle.setAttribute('aria-expanded', 'false');
});
}
});
// BS5 Tooltips
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
return new bootstrap.Tooltip(tooltipTriggerEl);
});
var tooltipTriggerList1 = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip-light"]'));
var tooltipList = tooltipTriggerList1.map(function (tooltipTriggerEl1) {
return new bootstrap.Tooltip(tooltipTriggerEl1, {
template:
'<div class="tooltip tooltip-light"><div class="tooltip-inner"></div></div>'
}
);
});
// Drawer
$(".open-right-drawer").click(function () {
$(this).addClass("is-active");
$(".app-drawer-wrapper").addClass("drawer-open");
$(".app-drawer-overlay").removeClass("d-none");
});
$(".drawer-nav-btn").click(function () {
$(".app-drawer-wrapper").removeClass("drawer-open");
$(".app-drawer-overlay").addClass("d-none");
$(".open-right-drawer").removeClass("is-active");
});
$(".app-drawer-overlay").click(function () {
$(this).addClass("d-none");
$(".app-drawer-wrapper").removeClass("drawer-open");
$(".open-right-drawer").removeClass("is-active");
});
$(".mobile-toggle-nav").click(function () {
$(this).toggleClass("is-active");
$(".app-container").toggleClass("sidebar-mobile-open");
});
$(".mobile-toggle-header-nav").click(function () {
$(this).toggleClass("active");
$(".app-header__content").toggleClass("header-mobile-open");
});
$(".mobile-app-menu-btn").click(function () {
$(".hamburger", this).toggleClass("is-active");
$(".app-inner-layout").toggleClass("open-mobile-menu");
});
// Responsive
var resizeClass = function () {
var win = document.body.clientWidth;
if (win < 1250) {
$(".app-container").addClass("closed-sidebar-mobile closed-sidebar");
} else {
$(".app-container").removeClass("closed-sidebar-mobile closed-sidebar");
}
};
$(window).on("resize", function () {
resizeClass();
});
resizeClass();
// Enhanced content loading animations
function animateCards() {
$('.main-card, .card').each(function(index) {
const $card = $(this);
setTimeout(() => {
$card.addClass('animated fadeInUp');
}, index * 50);
});
}
// Trigger card animations with delay for better visual effect
setTimeout(animateCards, 400);
// Handle dynamic tab content animations
$('a[data-bs-toggle="tab"]').on('shown.bs.tab', function (e) {
const targetPane = $($(e.target).attr('href'));
targetPane.addClass('TabsAnimation-appear');
setTimeout(() => {
targetPane.addClass('TabsAnimation-appear-active');
}, 50);
});
// Smooth loading overlay (optional enhancement)
function showPageLoader() {
if (!$('.page-loader').length) {
$('body').append(`
<div class="page-loader" style="
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(255,255,255,0.9);
z-index: 9999;
display: flex;
align-items: center;
justify-content: center;
">
<div class="loader">
<div class="ball-pulse">
<div></div>
<div></div>
<div></div>
</div>
</div>
</div>
`);
}
}
function hidePageLoader() {
$('.page-loader').fadeOut(300, function() {
$(this).remove();
});
}
// Auto-hide loader after animations complete
setTimeout(hidePageLoader, 800);
// Export animation utilities globally for other scripts
window.ArchitectUI = window.ArchitectUI || {};
window.ArchitectUI.animations = {
fadeInContent: fadeInContent,
initPageAnimations: initPageAnimations,
animateCards: animateCards
};
});