124 lines
4.5 KiB
JavaScript
124 lines
4.5 KiB
JavaScript
// SNAPSHOT
|
|
|
|
import './bootstrap';
|
|
import { createPopper } from "@popperjs/core";
|
|
import focus from "@alpinejs/focus";
|
|
import tagifyMin from "@yaireo/tagify";
|
|
import Echo from 'laravel-echo';
|
|
import Pusher from 'pusher-js';
|
|
import { Chart, registerables } from 'chart.js';
|
|
import './presence-tracker.js';
|
|
import './return-ratio-chart.js';
|
|
import './account-balances-chart.js';
|
|
|
|
|
|
Alpine.plugin(focus);
|
|
|
|
// Register Chart.js globally
|
|
Chart.register(...registerables);
|
|
window.Chart = Chart;
|
|
|
|
window.createPopper = createPopper;
|
|
window.Tagify = tagifyMin; // Needs to be loaded after Alpine
|
|
|
|
// Lazy-load JSZip (used by backup restore chunked upload)
|
|
window.loadJSZip = () => import('jszip').then(m => m.default);
|
|
|
|
// Alpine component for the call tag picker (livewire:calls.call-skill-input)
|
|
// Registered via Alpine.data() so Alpine can resolve it when Livewire morphs in new DOM nodes.
|
|
document.addEventListener('alpine:init', () => {
|
|
Alpine.data('callTagPicker', () => ({
|
|
callTagify: null,
|
|
init() {
|
|
const input = this.$refs.callTagsInput;
|
|
const suggestions = JSON.parse(input.dataset.suggestions || '[]');
|
|
|
|
this.callTagify = new Tagify(input, {
|
|
maxTags: 1,
|
|
whitelist: suggestions,
|
|
enforceWhiteList: false,
|
|
backspace: false,
|
|
editTags: false,
|
|
addTagOn: ['enter', 'tab'],
|
|
addTagOnBlur: false,
|
|
dropdown: {
|
|
maxItems: 10,
|
|
enabled: 2,
|
|
closeOnSelect: true,
|
|
highlightFirst: true,
|
|
},
|
|
});
|
|
|
|
// Pre-populate with initial value from server (e.g. edit modal)
|
|
const initialTags = this.$wire.get('tagsArray');
|
|
if (initialTags && initialTags !== '[]') {
|
|
this.callTagify.loadOriginalValues(initialTags);
|
|
}
|
|
|
|
this.callTagify.on('change', () => {
|
|
// Read from the actual input element — e.target can be a #text node in Tagify
|
|
const rawValue = this.$refs.callTagsInput.value;
|
|
const tags = JSON.parse(rawValue || '[]');
|
|
if (tags.length === 0) {
|
|
this.$wire.set('tagsArray', '[]', false);
|
|
this.$wire.call('notifyTagCleared');
|
|
return;
|
|
}
|
|
const tag = tags[0];
|
|
if (tag.tag_id) {
|
|
// Known tag — sync and notify parent
|
|
this.$wire.set('tagsArray', rawValue, false);
|
|
this.$wire.call('notifyTagSelected', tag.tag_id);
|
|
} else {
|
|
// Unknown tag — open creation modal (no set() to avoid re-render race)
|
|
this.$wire.call('openNewTagModal', tag.value);
|
|
}
|
|
});
|
|
|
|
// Server asks us to remove the pending unconfirmed tag (cancel modal)
|
|
window.addEventListener('removeLastCallTag', () => {
|
|
if (this.callTagify && this.callTagify.value.length > 0) {
|
|
this.callTagify.removeTag(
|
|
this.callTagify.value[this.callTagify.value.length - 1].value
|
|
);
|
|
}
|
|
});
|
|
|
|
// Server pushes a new tagsArray after createTag — reload Tagify with colored badge
|
|
Livewire.on('callTagifyReload', (data) => {
|
|
this.callTagify.loadOriginalValues(data.tagsArray);
|
|
});
|
|
}
|
|
}));
|
|
});
|
|
|
|
window.Pusher = Pusher;
|
|
|
|
// Get the current locale from the URL (e.g., /en/, /nl/, etc.)
|
|
const getLocalePrefix = () => {
|
|
const pathParts = window.location.pathname.split('/').filter(Boolean);
|
|
const locales = ['en', 'nl', 'de', 'es', 'fr'];
|
|
if (pathParts.length > 0 && locales.includes(pathParts[0])) {
|
|
return `/${pathParts[0]}`;
|
|
}
|
|
return '/en'; // Default to English if no locale found
|
|
};
|
|
|
|
window.Echo = new Echo({
|
|
broadcaster: 'reverb',
|
|
key: import.meta.env.VITE_REVERB_APP_KEY,
|
|
wsHost: import.meta.env.VITE_REVERB_HOST,
|
|
wsPort: import.meta.env.VITE_REVERB_PORT ?? 80,
|
|
wssPort: import.meta.env.VITE_REVERB_PORT ?? 443,
|
|
wsPath: import.meta.env.VITE_REVERB_PATH ?? "/",
|
|
forceTLS: (import.meta.env.VITE_REVERB_SCHEME ?? "https") === "https",
|
|
enabledTransports: ['ws', 'wss'],
|
|
authEndpoint: `${getLocalePrefix()}/broadcasting/auth`,
|
|
auth: {
|
|
headers: {
|
|
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')?.getAttribute('content')
|
|
}
|
|
}
|
|
});
|
|
|