ultimatepos/resources/views/layouts/partials/javascripts.blade.php

651 lines
26 KiB
PHP

<script type="text/javascript">
base_path = "{{ url('/') }}";
//used for push notification
APP = {};
APP.PUSHER_APP_KEY = '{{ config('broadcasting.connections.pusher.key') }}';
APP.PUSHER_APP_CLUSTER = '{{ config('broadcasting.connections.pusher.options.cluster') }}';
APP.PUSHER_SELF_HOSTED = {{ env('PUSHER_HOST') ? 'true' : 'false' }};
APP.PUSHER_WS_HOST = '{{ env('PUSHER_HOST', '127.0.0.1') }}';
APP.PUSHER_WS_PORT = {{ (int) env('PUSHER_PORT', 6001) }};
APP.PUSHER_USE_TLS = {{ env('PUSHER_SCHEME', 'https') === 'https' ? 'true' : 'false' }};
APP.INVOICE_SCHEME_SEPARATOR = '{{ config('constants.invoice_scheme_separator') }}';
//variable from app service provider
// Defer vendor.js Echo init when using self-hosted WebSocket (re-init after vendor loads)
APP.PUSHER_ENABLED = '{{ env('PUSHER_HOST') && $__is_pusher_enabled ? '' : $__is_pusher_enabled }}';
@auth
@php
$user = Auth::user();
@endphp
APP.USER_ID = "{{ $user->id }}";
@else
APP.USER_ID = '';
@endauth
</script>
@php
$is_persian = is_persian_lang();
// Set default Persian date format if Persian language
if ($is_persian) {
$business_date_format = session('business.date_format', 'Y/m/d');
} else {
$business_date_format = session('business.date_format', config('constants.default_date_format'));
}
// For Persian datepicker
if ($is_persian) {
$datepicker_date_format = 'YYYY/MM/DD';
} else {
$datepicker_date_format = str_replace('d', 'dd', $business_date_format);
$datepicker_date_format = str_replace('m', 'mm', $datepicker_date_format);
$datepicker_date_format = str_replace('Y', 'yyyy', $datepicker_date_format);
}
// For moment.js display (Jalali tokens for Persian UI)
if ($is_persian) {
$moment_date_format = 'jYYYY/jMM/jDD';
$daterangepicker_format = 'YYYY/MM/DD';
} else {
$moment_date_format = str_replace('d', 'DD', $business_date_format);
$moment_date_format = str_replace('m', 'MM', $moment_date_format);
$moment_date_format = str_replace('Y', 'YYYY', $moment_date_format);
$daterangepicker_format = $moment_date_format;
}
$business_time_format = session('business.time_format');
$moment_time_format = 'HH:mm';
if ($business_time_format == 12) {
$moment_time_format = 'hh:mm A';
}
$common_settings = !empty(session('business.common_settings')) ? session('business.common_settings') : [];
$default_datatable_page_entries = !empty($common_settings['default_datatable_page_entries'])
? $common_settings['default_datatable_page_entries']
: 25;
@endphp
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js?v=$asset_v"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js?v=$asset_v"></script>
<![endif]-->
<script src="{{ asset('js/vendor.js?v=' . $asset_v) }}"></script>
@if($is_persian)
<script src="{{ asset('plugins/moment-jalaali/moment-jalaali.js?v=' . $asset_v) }}"></script>
<script src="{{ asset('plugins/persian-date/persian-date.min.js?v=' . $asset_v) }}"></script>
<script src="{{ asset('plugins/persian-datepicker/js/persian-datepicker.min.js?v=' . $asset_v) }}"></script>
@endif
@if (env('PUSHER_HOST') && $__is_pusher_enabled)
<script>
(function () {
if (typeof APP === 'undefined' || !APP.PUSHER_SELF_HOSTED || typeof Pusher === 'undefined' || typeof Echo === 'undefined') {
return;
}
if (window.Echo && window.Echo.connector && window.Echo.connector.pusher) {
try { window.Echo.connector.pusher.disconnect(); } catch (e) {}
}
window.Echo = new Echo({
authEndpoint: base_path + '/broadcasting/auth',
broadcaster: 'pusher',
key: APP.PUSHER_APP_KEY,
wsHost: APP.PUSHER_WS_HOST,
wsPort: APP.PUSHER_WS_PORT,
wssPort: APP.PUSHER_WS_PORT,
forceTLS: APP.PUSHER_USE_TLS,
encrypted: APP.PUSHER_USE_TLS,
disableStats: true,
enabledTransports: ['ws', 'wss'],
});
APP.PUSHER_ENABLED = true;
if (APP.USER_ID && typeof Notification !== 'undefined') {
if (Notification.permission !== 'denied' || Notification.permission === 'default') {
Notification.requestPermission();
}
window.Echo.private('App.User.' + APP.USER_ID).notification(function (notification) {
if (Notification.permission !== 'granted') return;
var options = { body: notification.body };
var title = notification.title || '';
var obj = new Notification(title, options);
if (notification.link) {
obj.onclick = function () { window.open(notification.link); };
}
});
}
})();
</script>
@endif
@if (file_exists(public_path('js/lang/' . session()->get('user.language', config('app.locale')) . '.js')))
<script src="{{ asset('js/lang/' . session()->get('user.language', config('app.locale')) . '.js?v=' . $asset_v) }}">
</script>
@else
<script src="{{ asset('js/lang/en.js?v=' . $asset_v) }}"></script>
@endif
<script>
Dropzone.autoDiscover = false;
@if($is_persian)
// Configure moment for Persian calendar
if (typeof moment !== 'undefined' && typeof moment.loadPersian === 'function') {
moment.loadPersian({dialect: 'persian-modern'});
}
@endif
moment.tz.setDefault('{{ Session::get('business.time_zone') }}');
$(document).ready(function() {
// Setup CSRF token for all Ajax requests
// Ensure CSRF token is set (may have been set in common.js, but we ensure it here too)
var csrfToken = $('meta[name="csrf-token"]').attr('content');
if (csrfToken) {
// Merge with existing Ajax setup (from common.js)
var existingBeforeSend = $.ajaxSettings.beforeSend;
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': csrfToken
},
beforeSend: function(jqXHR, settings) {
// Call existing beforeSend if it exists
if (existingBeforeSend && typeof existingBeforeSend === 'function') {
var result = existingBeforeSend.call(this, jqXHR, settings);
if (result === false) {
return false;
}
}
// Ensure CSRF token is set
if (!jqXHR.headers || !jqXHR.headers['X-CSRF-TOKEN']) {
var token = $('meta[name="csrf-token"]').attr('content') || csrfToken;
if (token) {
jqXHR.setRequestHeader('X-CSRF-TOKEN', token);
}
}
}
});
} else {
console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}
@if (config('app.debug') == false)
$.fn.dataTable.ext.errMode = 'throw';
@endif
});
var financial_year = {
start: moment('{{ Session::get('financial_year.start') }}', 'YYYY-MM-DD'),
end: moment('{{ Session::get('financial_year.end') }}', 'YYYY-MM-DD'),
}
@if (file_exists(public_path('AdminLTE/plugins/select2/lang/' . session()->get('user.language', config('app.locale')) . '.js')))
//Default setting for select2
$.fn.select2.defaults.set("language", "{{ session()->get('user.language', config('app.locale')) }}");
@endif
var datepicker_date_format = "{{ $datepicker_date_format }}";
var moment_date_format = "{{ $moment_date_format }}";
var daterangepicker_format = "{{ $daterangepicker_format }}";
var moment_time_format = "{{ $moment_time_format }}";
var is_persian_lang = {{ $is_persian ? 'true' : 'false' }};
var app_locale = "{{ session()->get('user.language', config('app.locale')) }}";
var non_utf8_languages = [
@foreach (config('constants.non_utf8_languages') as $const)
"{{ $const }}",
@endforeach
];
var __default_datatable_page_entries = "{{ $default_datatable_page_entries }}";
var __new_notification_count_interval = "{{ config('constants.new_notification_count_interval', 60) }}000";
</script>
@if (file_exists(public_path('js/lang/' . session()->get('user.language', config('app.locale')) . '.js')))
<script src="{{ asset('js/lang/' . session()->get('user.language', config('app.locale')) . '.js?v=' . $asset_v) }}">
</script>
@else
<script src="{{ asset('js/lang/en.js?v=' . $asset_v) }}"></script>
@endif
<script src="{{ asset('js/functions.js?v=' . $asset_v) }}"></script>
<script src="{{ asset('js/common.js?v=' . $asset_v) }}"></script>
@if (empty($portal_mode))
<script src="{{ asset('js/app.js?v=' . $asset_v) }}"></script>
@endif
@if (empty($portal_mode))
<script src="{{ asset('js/help-tour.js?v=' . $asset_v) }}"></script>
<script src="{{ asset('js/documents_and_note.js?v=' . $asset_v) }}"></script>
@endif
<!-- TODO -->
@if (file_exists(public_path('AdminLTE/plugins/select2/lang/' . session()->get('user.language', config('app.locale')) . '.js')))
<script
src="{{ asset('AdminLTE/plugins/select2/lang/' . session()->get('user.language', config('app.locale')) . '.js?v=' . $asset_v) }}">
</script>
@endif
@php
$validation_lang_file = 'messages_' . session()->get('user.language', config('app.locale')) . '.js';
@endphp
@if (file_exists(public_path() . '/js/jquery-validation-1.16.0/src/localization/' . $validation_lang_file))
<script src="{{ asset('js/jquery-validation-1.16.0/src/localization/' . $validation_lang_file . '?v=' . $asset_v) }}">
</script>
@endif
@if (!empty($__system_settings['additional_js']))
{!! $__system_settings['additional_js'] !!}
@endif
@yield('javascript')
@if (Module::has('Essentials') && empty($portal_mode))
@includeIf('essentials::layouts.partials.footer_part')
@endif
<script type="text/javascript">
$(document).ready(function() {
var locale = "{{ session()->get('user.language', config('app.locale')) }}";
var isRTL =
@if (in_array(session()->get('user.language', config('app.locale')), config('constants.langs_rtl')))
true;
@else
false;
@endif
@if (empty($portal_mode))
if ($('#calendar').length) {
$('#calendar').fullCalendar('option', {
locale: locale,
isRTL: isRTL
});
}
// side bar toggle
$(".drop_down").click(function(event) {
event.preventDefault();
var $item = $(this).closest('.sidebar-item');
var $chiled = $(this).next(".chiled");
$(".chiled").not($chiled).slideUp();
$(".sidebar-item").not($item).removeClass('selected');
$chiled.slideToggle(function() {
$item.toggleClass('selected', $chiled.is(':visible'));
});
});
$('.small-view-button').on('click', function() {
$('#main-wrapper').addClass('show-sidebar');
$('.matdash-sidebar').addClass('small-view-side-active');
$('body').addClass('sidebar-drawer-open');
$('.overlay').fadeIn('slow');
});
$('.overlay').on('click', function() {
$('.overlay').fadeOut('slow');
$('#main-wrapper').removeClass('show-sidebar');
$('.matdash-sidebar').removeClass('small-view-side-active');
$('body').removeClass('sidebar-drawer-open');
});
$(window).on('resize', function() {
if ($(window).width() >= 1200) {
$('.overlay').fadeOut('slow');
$('#main-wrapper').removeClass('show-sidebar');
$('.matdash-sidebar').removeClass('small-view-side-active');
$('body').removeClass('sidebar-drawer-open');
}
if ($('.matdash-sidebar').hasClass('small-view-side-active')) {
$('.overlay').fadeIn('slow');
}
});
/* Close drawer when a sidebar link is tapped on mobile/tablet */
$(document).on('click', '.matdash-sidebar .sidebar-link', function() {
if ($(window).width() < 1200 && !$(this).hasClass('has-arrow')) {
$('.overlay').trigger('click');
}
});
$(document).on('click', function (e) {
$('[data-toggle="popover"]').not('.hover-q').popover();
$(document).on('click', function (e) {
$('[data-toggle="popover"]').each(function () {
// Check if the clicked element is the popover button or inside the popover
if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
$(this).popover('hide');
}
});
});
});
$('.side-bar-collapse').click(function() {
$('body').toggleClass('sidebar-hidden');
localStorage.setItem("upos_sidebar_collapse", $('body').hasClass('sidebar-hidden'));
});
if (localStorage.getItem("upos_sidebar_collapse") == 'true') {
$('body').addClass('sidebar-hidden');
}
$('.sidebar-compact-toggle').on('click', function() {
$('body').toggleClass('sidebar-compact');
$(this).toggleClass('is-active', $('body').hasClass('sidebar-compact'));
localStorage.setItem('upos_sidebar_compact', $('body').hasClass('sidebar-compact'));
});
if (localStorage.getItem('upos_sidebar_compact') === 'true') {
$('body').addClass('sidebar-compact');
$('.sidebar-compact-toggle').addClass('is-active');
}
$(document).on('keydown', function(e) {
if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 'k') {
var $search = $('#sidebar-menu-search');
if ($search.length) {
e.preventDefault();
$search.trigger('focus');
}
}
});
@php
$menuGroupConfigJson = collect(config('admin_menu_groups', []))->mapWithKeys(function ($group, $key) {
return [$key => [
'icon' => $group['icon'] ?? 'fa-folder',
'default_expanded' => ! empty($group['default_expanded']),
]];
});
@endphp
var menuGroupConfig = {!! $menuGroupConfigJson->toJson() !!};
var FREQUENT_MENU_KEY = 'upos_menu_frequent';
var FREQUENT_MENU_MAX = 5;
function normalizeMenuUrl(url) {
try {
var a = document.createElement('a');
a.href = url;
return a.pathname.replace(/\/+$/, '') || '/';
} catch (e) {
return url;
}
}
function expandMenuGroup(groupKey) {
var $cap = $('#side-bar .nav-small-cap--collapsible[data-group="' + groupKey + '"]');
if (!$cap.length) {
return;
}
$cap.removeClass('nav-small-cap--collapsed');
$cap.nextUntil('.nav-small-cap').removeClass('nav-small-cap-group-hidden');
localStorage.setItem('upos_menu_group_' + groupKey, 'expanded');
if ($cap[0] && document.getElementById('side-bar')) {
$cap[0].scrollIntoView({ behavior: 'smooth', block: 'nearest' });
}
}
function highlightActiveIconbarGroup() {
$('.matdash-group-nav-item').removeClass('is-active');
var $active = $('#side-bar .sidebar-link.active').first();
if (!$active.length) {
return;
}
var $topItem = $active.closest('#side-bar > .sidebar-menu > .sidebar-item');
var $groupCap = $topItem.prevAll('.nav-small-cap--collapsible').first();
var groupKey = $groupCap.data('group');
if (groupKey) {
$('.matdash-group-jump-btn[data-group="' + groupKey + '"]').closest('.matdash-group-nav-item').addClass('is-active');
}
}
function buildIconbarGroups() {
var $nav = $('#matdash-group-nav');
if (!$nav.length) {
return;
}
$nav.empty();
$('#side-bar .nav-small-cap--collapsible').each(function() {
var $cap = $(this);
var groupKey = $cap.data('group');
if (!groupKey) {
return;
}
var label = $cap.find('.hide-menu').first().text().trim();
var icon = (menuGroupConfig[groupKey] && menuGroupConfig[groupKey].icon) ? menuGroupConfig[groupKey].icon : 'fa-folder';
var $li = $('<li class="matdash-mini-nav-item matdash-group-nav-item"></li>');
var $btn = $('<button type="button" class="matdash-group-jump-btn" title="' + label + '" data-group="' + groupKey + '"><span class="matdash-mini-icon-box"><i class="fas ' + icon + '"></i></span></button>');
$li.append($btn);
$nav.append($li);
});
highlightActiveIconbarGroup();
}
function recordMenuVisit(url, title) {
if (!url || url === '#' || url.indexOf('javascript:') === 0) {
return;
}
var path = normalizeMenuUrl(url);
var items = [];
try {
items = JSON.parse(localStorage.getItem(FREQUENT_MENU_KEY) || '[]');
} catch (e) {
items = [];
}
var found = null;
for (var i = 0; i < items.length; i++) {
if (normalizeMenuUrl(items[i].url) === path) {
found = items[i];
break;
}
}
if (found) {
found.count = (found.count || 0) + 1;
found.title = title;
found.ts = Date.now();
} else {
items.push({ url: url, title: title, count: 1, ts: Date.now() });
}
items.sort(function(a, b) {
return (b.count - a.count) || (b.ts - a.ts);
});
localStorage.setItem(FREQUENT_MENU_KEY, JSON.stringify(items.slice(0, 20)));
renderQuickAccess();
}
function renderQuickAccess() {
var $wrap = $('#sidebar-quick-access');
var $list = $('#sidebar-quick-access-list');
if (!$wrap.length || !$list.length) {
return;
}
var items = [];
try {
items = JSON.parse(localStorage.getItem(FREQUENT_MENU_KEY) || '[]');
} catch (e) {
items = [];
}
var menuLinks = {};
$('#side-bar .sidebar-link[href]').each(function() {
var href = $(this).attr('href');
if (!href || $(this).hasClass('has-arrow')) {
return;
}
menuLinks[normalizeMenuUrl(href)] = {
url: href,
title: $(this).find('.hide-menu').first().text().trim()
};
});
var shown = 0;
$list.empty();
for (var i = 0; i < items.length && shown < FREQUENT_MENU_MAX; i++) {
var path = normalizeMenuUrl(items[i].url);
var live = menuLinks[path];
if (!live || !live.title) {
continue;
}
shown++;
$list.append(
'<li class="sidebar-item"><a href="' + live.url + '" class="sidebar-link sidebar-quick-link">' +
'<span class="icon-small"></span><span class="hide-menu">' + live.title + '</span></a></li>'
);
}
$wrap.toggleClass('tw-hidden', shown === 0);
}
function expandMenuGroupsForSearch() {
$('#side-bar > .sidebar-menu > .nav-small-cap').each(function() {
var $cap = $(this);
var hasVisible = $cap.nextUntil('.nav-small-cap').filter('.sidebar-item:not(.sidebar-item-hidden)').length > 0;
$cap.toggleClass('nav-small-cap-hidden', !hasVisible);
if (hasVisible && $cap.hasClass('nav-small-cap--collapsible')) {
$cap.removeClass('nav-small-cap--collapsed');
$cap.nextUntil('.nav-small-cap').removeClass('nav-small-cap-group-hidden');
}
});
}
function initMenuGroupAccordion() {
$('#side-bar > .sidebar-menu > .nav-small-cap--collapsible').each(function() {
var $cap = $(this);
var groupKey = $cap.data('group');
if (!groupKey) {
return;
}
var $items = $cap.nextUntil('.nav-small-cap');
var hasActive = $items.find('.sidebar-link.active').length > 0;
var stored = localStorage.getItem('upos_menu_group_' + groupKey);
var defaultExpanded = menuGroupConfig[groupKey] && menuGroupConfig[groupKey].default_expanded;
var collapsed;
if (hasActive) {
collapsed = false;
} else if (stored === 'expanded') {
collapsed = false;
} else if (stored === 'collapsed') {
collapsed = true;
} else {
collapsed = !defaultExpanded;
}
$cap.toggleClass('nav-small-cap--collapsed', collapsed);
$items.toggleClass('nav-small-cap-group-hidden', collapsed);
});
highlightActiveIconbarGroup();
}
$(document).on('click', '.nav-small-cap--collapsible', function(e) {
if ($(e.target).closest('.nav-small-cap-toggle').length === 0 && !$(e.target).hasClass('nav-small-cap-toggle')) {
// allow click anywhere on cap
}
var $cap = $(this);
var groupKey = $cap.data('group');
if (!groupKey) {
return;
}
var collapsed = !$cap.hasClass('nav-small-cap--collapsed');
$cap.toggleClass('nav-small-cap--collapsed', collapsed);
$cap.nextUntil('.nav-small-cap').toggleClass('nav-small-cap-group-hidden', collapsed);
localStorage.setItem('upos_menu_group_' + groupKey, collapsed ? 'collapsed' : 'expanded');
highlightActiveIconbarGroup();
});
$(document).on('click', '.matdash-group-jump-btn', function() {
var groupKey = $(this).data('group');
expandMenuGroup(groupKey);
$('.matdash-group-nav-item').removeClass('is-active');
$(this).closest('.matdash-group-nav-item').addClass('is-active');
if ($('body').hasClass('sidebar-hidden')) {
$('body').removeClass('sidebar-hidden');
localStorage.setItem('upos_sidebar_collapse', 'false');
}
});
$(document).on('click', '#side-bar .sidebar-link, .sidebar-quick-access-list .sidebar-link', function() {
if ($(this).hasClass('has-arrow')) {
return;
}
var url = $(this).attr('href');
var title = $(this).find('.hide-menu').first().text().trim();
recordMenuVisit(url, title);
});
initMenuGroupAccordion();
buildIconbarGroups();
renderQuickAccess();
/* Sidebar menu search */
$('#sidebar-menu-search').on('input', function() {
var query = $(this).val().toLowerCase().trim();
if (!query.length) {
$('#side-bar .sidebar-item-hidden').removeClass('sidebar-item-hidden');
$('#side-bar .nav-small-cap-hidden').removeClass('nav-small-cap-hidden');
$('#side-bar .nav-small-cap-group-hidden').removeClass('nav-small-cap-group-hidden');
$('#side-bar .sidebar-item').each(function() {
var $item = $(this);
if (!$item.hasClass('selected')) {
$item.children('.chiled').hide();
}
});
initMenuGroupAccordion();
return;
}
$('#side-bar > .sidebar-menu > .sidebar-item').each(function() {
var $item = $(this);
if ($item.children('.drop_down').length) {
var groupMatch = $item.children('.drop_down').text().toLowerCase().indexOf(query) !== -1;
$item.find('.chiled .sidebar-link').each(function() {
var childMatch = $(this).text().toLowerCase().indexOf(query) !== -1;
$(this).closest('.sidebar-item').toggleClass('sidebar-item-hidden', !childMatch && !groupMatch);
if (childMatch) groupMatch = true;
});
$item.toggleClass('sidebar-item-hidden', !groupMatch);
if (groupMatch) {
$item.addClass('selected');
$item.children('.chiled').show();
}
} else {
var match = $item.children('.sidebar-link').text().toLowerCase().indexOf(query) !== -1;
$item.toggleClass('sidebar-item-hidden', !match);
}
});
expandMenuGroupsForSearch();
});
@endif
$('.dt-buttons.btn-group').find('a.btn').removeClass('btn-default');
$('.dt-buttons.btn-group').find('a.btn').removeClass('btn');
// $('.date_range').on('show.daterangepicker', function (ev, picker) {
// $(picker.container).insertAfter($(this));
// });
});
</script>