Files
pulse-signage/src/web/public/js/announcements/announcement-form.js
T
2026-08-05 19:38:16 +01:00

421 lines
14 KiB
JavaScript

function updateAnnouncementDurationFields() {
var modeSelect = document.getElementById('announcement-duration-mode');
var durationFields = document.querySelector('[data-announcement-duration-value-fields]');
if (!modeSelect || !durationFields) {
return;
}
var durationValueInput = document.getElementById('announcement-duration-value');
var durationUnitSelect = document.getElementById('announcement-duration-unit');
var isDurationMode = String(modeSelect.value || '').trim() === 'duration';
durationFields.hidden = !isDurationMode;
if (durationValueInput) {
durationValueInput.disabled = !isDurationMode;
}
if (durationUnitSelect) {
durationUnitSelect.disabled = !isDurationMode;
}
}
function updateAnnouncementColorPickerSelection() {
var colorInput = document.getElementById('announcement-color');
var picker = document.querySelector('[data-announcement-color-picker-shell]');
if (!colorInput || !picker) {
return;
}
var selectedValue = String(colorInput.value || '').trim().toLowerCase() || 'primary';
picker.querySelectorAll('[data-announcement-color-option]').forEach(function (button) {
var isSelected = String(button.getAttribute('data-color-key') || '').trim().toLowerCase() === selectedValue;
button.classList.toggle('is-selected', isSelected);
button.setAttribute('aria-pressed', isSelected ? 'true' : 'false');
});
}
function setAnnouncementScreenSelection(isSelected) {
document.querySelectorAll('input[name="screen_ids[]"]').forEach(function (input) {
input.checked = isSelected;
});
}
function positionAnnouncementTypePicker() {
var picker = document.querySelector('[data-announcement-type-picker]');
var toggle = document.querySelector('[data-announcement-type-picker-toggle]');
var shell = document.querySelector('[data-announcement-type-picker-shell]');
if (!picker || picker.hidden || !toggle || !shell) {
return;
}
var padding = 8;
var toggleRect = toggle.getBoundingClientRect();
var menuRect = picker.getBoundingClientRect();
var viewportHeight = window.innerHeight || document.documentElement.clientHeight || toggleRect.bottom;
var placementAbove = false;
var spaceBelow = viewportHeight - toggleRect.bottom - padding;
var spaceAbove = toggleRect.top - padding;
if (menuRect.height > spaceBelow && spaceAbove > spaceBelow) {
placementAbove = true;
}
picker.classList.toggle('is-open-above', placementAbove);
}
function closeAnnouncementTypePicker() {
var picker = document.querySelector('[data-announcement-type-picker]');
var toggle = document.querySelector('[data-announcement-type-picker-toggle]');
if (!picker) {
return;
}
picker.hidden = true;
picker.classList.remove('is-open-above');
if (toggle) {
toggle.setAttribute('aria-expanded', 'false');
}
}
function openAnnouncementTypePicker() {
var picker = document.querySelector('[data-announcement-type-picker]');
var toggle = document.querySelector('[data-announcement-type-picker-toggle]');
if (!picker) {
return;
}
picker.hidden = false;
if (toggle) {
toggle.setAttribute('aria-expanded', 'true');
}
if (typeof window !== 'undefined' && window.requestAnimationFrame) {
window.requestAnimationFrame(positionAnnouncementTypePicker);
} else {
positionAnnouncementTypePicker();
}
}
function updateAnnouncementTypePickerSelection() {
var typeInput = document.getElementById('announcement-type');
var previewButton = document.querySelector('[data-announcement-type-picker-toggle]');
var picker = document.querySelector('[data-announcement-type-picker]');
if (!typeInput || !previewButton || !picker) {
return;
}
var selectedValue = String(typeInput.value || '').trim().toLowerCase();
var selectedOption = picker.querySelector('[data-announcement-type-option][data-type-key="' + selectedValue + '"]');
var label = selectedOption ? String(selectedOption.getAttribute('data-type-label') || selectedOption.textContent || selectedValue).trim() : selectedValue;
var iconKey = selectedOption ? String(selectedOption.getAttribute('data-type-icon') || '').trim().toLowerCase() : '';
var icon = previewButton.querySelector('[data-announcement-type-picker-icon]');
var text = previewButton.querySelector('[data-announcement-type-picker-label]');
previewButton.setAttribute('aria-label', label);
previewButton.setAttribute('title', label);
if (icon) {
icon.className = 'bi bi-' + iconKey;
}
if (text) {
text.textContent = label;
}
picker.querySelectorAll('[data-announcement-type-option]').forEach(function (button) {
var isSelected = String(button.getAttribute('data-type-key') || '').trim().toLowerCase() === selectedValue;
button.classList.toggle('is-selected', isSelected);
button.setAttribute('aria-pressed', isSelected ? 'true' : 'false');
});
}
function setAnnouncementTypeValue(typeKey) {
var typeInput = document.getElementById('announcement-type');
if (!typeInput) {
return;
}
var normalized = String(typeKey || '').trim().toLowerCase();
if (!normalized) {
return;
}
typeInput.value = normalized;
updateAnnouncementTypePickerSelection();
}
function updateAnnouncementIconPreview() {
var iconSelect = document.getElementById('announcement-icon');
var preview = document.querySelector('[data-announcement-icon-preview]');
if (!iconSelect || !preview) {
return;
}
var selectedOption = iconSelect.options[iconSelect.selectedIndex] || null;
var iconKey = selectedOption ? String(selectedOption.value || '').trim().toLowerCase() : '';
var label = selectedOption ? String(selectedOption.textContent || selectedOption.label || iconKey).trim() : iconKey;
preview.className = 'announcement-icon-preview';
preview.innerHTML = '<i class="bi bi-' + iconKey + '" aria-hidden="true"></i>';
preview.setAttribute('aria-label', label);
preview.setAttribute('title', label);
}
function positionAnnouncementIconPicker() {
var picker = document.querySelector('[data-announcement-icon-picker]');
var toggle = document.querySelector('[data-announcement-icon-picker-toggle]');
var shell = document.querySelector('[data-announcement-icon-picker-shell]');
if (!picker || picker.hidden || !toggle || !shell) {
return;
}
var padding = 8;
var toggleRect = toggle.getBoundingClientRect();
var menuRect = picker.getBoundingClientRect();
var viewportHeight = window.innerHeight || document.documentElement.clientHeight || toggleRect.bottom;
var placementAbove = false;
var spaceBelow = viewportHeight - toggleRect.bottom - padding;
var spaceAbove = toggleRect.top - padding;
if (menuRect.height > spaceBelow && spaceAbove > spaceBelow) {
placementAbove = true;
}
picker.classList.toggle('is-open-above', placementAbove);
}
function closeAnnouncementIconPicker() {
var picker = document.querySelector('[data-announcement-icon-picker]');
var toggle = document.querySelector('[data-announcement-icon-picker-toggle]');
if (!picker) {
return;
}
picker.hidden = true;
picker.classList.remove('is-open-above');
if (toggle) {
toggle.setAttribute('aria-expanded', 'false');
}
}
function openAnnouncementIconPicker() {
var picker = document.querySelector('[data-announcement-icon-picker]');
var toggle = document.querySelector('[data-announcement-icon-picker-toggle]');
if (!picker) {
return;
}
picker.hidden = false;
if (toggle) {
toggle.setAttribute('aria-expanded', 'true');
}
if (typeof window !== 'undefined' && window.requestAnimationFrame) {
window.requestAnimationFrame(positionAnnouncementIconPicker);
} else {
positionAnnouncementIconPicker();
}
}
function updateAnnouncementIconPickerSelection() {
var iconSelect = document.getElementById('announcement-icon');
var previewButton = document.querySelector('[data-announcement-icon-picker-toggle]');
var picker = document.querySelector('[data-announcement-icon-picker]');
if (!iconSelect || !previewButton || !picker) {
return;
}
var selectedOption = iconSelect.options[iconSelect.selectedIndex] || null;
var selectedValue = selectedOption ? String(selectedOption.value || '').trim().toLowerCase() : '';
var label = selectedOption ? String(selectedOption.textContent || selectedOption.label || selectedValue).trim() : selectedValue;
var icon = previewButton.querySelector('[data-announcement-icon-picker-icon]');
var text = previewButton.querySelector('[data-announcement-icon-picker-label]');
previewButton.setAttribute('aria-label', label);
previewButton.setAttribute('title', label);
if (icon) {
icon.className = 'bi bi-' + selectedValue;
}
if (text) {
text.textContent = label;
}
picker.querySelectorAll('[data-announcement-icon-option]').forEach(function (button) {
var isSelected = String(button.getAttribute('data-icon-key') || '').trim().toLowerCase() === selectedValue;
button.classList.toggle('is-selected', isSelected);
button.setAttribute('aria-pressed', isSelected ? 'true' : 'false');
});
}
function setAnnouncementIconValue(iconKey) {
var iconSelect = document.getElementById('announcement-icon');
if (!iconSelect) {
return;
}
var normalized = String(iconKey || '').trim().toLowerCase();
if (!normalized) {
return;
}
iconSelect.value = normalized;
updateAnnouncementIconPreview();
updateAnnouncementIconPickerSelection();
}
function initAnnouncementForm() {
var typeInput = document.getElementById('announcement-type');
var typePickerToggle = document.querySelector('[data-announcement-type-picker-toggle]');
var typePicker = document.querySelector('[data-announcement-type-picker]');
var typePickerClose = document.querySelector('[data-announcement-type-picker-close]');
var modeSelect = document.getElementById('announcement-duration-mode');
var colorInput = document.getElementById('announcement-color');
var colorPicker = document.querySelector('[data-announcement-color-picker-shell]');
var screenSelectAll = document.querySelector('[data-announcement-screen-select-all]');
var screenSelectNone = document.querySelector('[data-announcement-screen-select-none]');
var iconSelect = document.getElementById('announcement-icon');
var iconPickerToggle = document.querySelector('[data-announcement-icon-picker-toggle]');
var iconPicker = document.querySelector('[data-announcement-icon-picker]');
var iconPickerClose = document.querySelector('[data-announcement-icon-picker-close]');
if (typeInput) {
updateAnnouncementTypePickerSelection();
}
if (typePickerToggle) {
typePickerToggle.addEventListener('click', function (event) {
event.preventDefault();
var isExpanded = typePicker && !typePicker.hidden;
if (isExpanded) {
closeAnnouncementTypePicker();
} else {
openAnnouncementTypePicker();
}
});
}
if (typePickerClose) {
typePickerClose.addEventListener('click', function (event) {
event.preventDefault();
closeAnnouncementTypePicker();
});
}
if (typePicker) {
typePicker.addEventListener('click', function (event) {
var button = event.target && event.target.closest ? event.target.closest('[data-announcement-type-option]') : null;
if (!button) {
return;
}
event.preventDefault();
setAnnouncementTypeValue(button.getAttribute('data-type-key'));
closeAnnouncementTypePicker();
});
}
if (modeSelect) {
modeSelect.addEventListener('change', updateAnnouncementDurationFields);
updateAnnouncementDurationFields();
}
if (colorInput) {
updateAnnouncementColorPickerSelection();
}
if (colorPicker) {
colorPicker.addEventListener('click', function (event) {
var button = event.target && event.target.closest ? event.target.closest('[data-announcement-color-option]') : null;
if (!button) {
return;
}
event.preventDefault();
colorInput.value = String(button.getAttribute('data-color-key') || '').trim().toLowerCase();
updateAnnouncementColorPickerSelection();
});
}
if (screenSelectAll) {
screenSelectAll.addEventListener('click', function (event) {
event.preventDefault();
setAnnouncementScreenSelection(true);
});
}
if (screenSelectNone) {
screenSelectNone.addEventListener('click', function (event) {
event.preventDefault();
setAnnouncementScreenSelection(false);
});
}
if (iconSelect) {
iconSelect.addEventListener('change', updateAnnouncementIconPreview);
updateAnnouncementIconPreview();
}
if (iconPickerToggle) {
iconPickerToggle.addEventListener('click', function (event) {
event.preventDefault();
var isExpanded = iconPicker && !iconPicker.hidden;
if (isExpanded) {
closeAnnouncementIconPicker();
} else {
openAnnouncementIconPicker();
}
});
}
if (iconPickerClose) {
iconPickerClose.addEventListener('click', function (event) {
event.preventDefault();
closeAnnouncementIconPicker();
});
}
if (iconPicker) {
iconPicker.addEventListener('click', function (event) {
var button = event.target && event.target.closest ? event.target.closest('[data-announcement-icon-option]') : null;
if (!button) {
return;
}
event.preventDefault();
setAnnouncementIconValue(button.getAttribute('data-icon-key'));
closeAnnouncementIconPicker();
});
}
window.addEventListener('resize', positionAnnouncementIconPicker);
window.addEventListener('resize', positionAnnouncementTypePicker);
document.addEventListener('click', function (event) {
var typePickerNode = document.querySelector('[data-announcement-type-picker]');
var typeToggleNode = document.querySelector('[data-announcement-type-picker-toggle]');
if (typePickerNode && !typePickerNode.hidden) {
if (!(typePickerNode.contains(event.target) || (typeToggleNode && typeToggleNode.contains(event.target)))) {
closeAnnouncementTypePicker();
}
}
var picker = document.querySelector('[data-announcement-icon-picker]');
var toggle = document.querySelector('[data-announcement-icon-picker-toggle]');
if (!picker || picker.hidden) {
return;
}
if (picker.contains(event.target) || (toggle && toggle.contains(event.target))) {
return;
}
closeAnnouncementIconPicker();
});
updateAnnouncementIconPickerSelection();
}
if (typeof document !== 'undefined') {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initAnnouncementForm, { once: true });
} else {
initAnnouncementForm();
}
}