(function() {
'use strict';
// Party presets for archive browser — IIFE module
// State (module scope, NOT on window.app)
let presets = [];
let activePresetName = null;
let isOpen = false;
let isNamingMode = false;
// Get localStorage key based on source mode and directory
function getStorageKey() {
if (window.app.sourceMode === 'http' && window.app.directories.length > 0) {
var u = window.app.directories[0].url || '';
return 'zddc-presets:http:' + u;
} else if (window.app.sourceMode === 'local' && window.app.directories.length > 0) {
return 'zddc-presets:local:' + window.app.directories[0].name;
}
return 'zddc-presets:default';
}
// Load presets from localStorage
function loadFromStorage() {
try {
var stored = localStorage.getItem(getStorageKey());
if (stored) {
var parsed = JSON.parse(stored);
if (parsed && Array.isArray(parsed.presets)) {
presets = parsed.presets;
} else {
presets = [];
}
} else {
presets = [];
}
} catch (e) {
presets = [];
}
}
// Save presets to localStorage
function saveToStorage() {
try {
localStorage.setItem(getStorageKey(), JSON.stringify({ presets: presets }));
} catch (e) {
// Silently fail on storage errors
}
}
// Load a preset by name
function loadPreset(name) {
var preset = presets.find(p => p.name === name);
if (!preset) return;
// Filter paths to only include folders that exist in groupingFolders
var validPaths = preset.paths.filter(p =>
window.app.groupingFolders.some(f => f.path === p)
);
window.app.selectedGroupingFolders = new Set(validPaths);
window.app.selectAllGroupingFolders = false;
var checkbox = document.getElementById('selectAllGroupingCheckbox');
if (checkbox) checkbox.checked = false;
activePresetName = name;
// Trigger UI updates
window.app.modules.app.updateFolderSelectionState('groupingFoldersList');
window.app.modules.app.renderTransmittalFolders();
window.app.modules.filtering.applyFilters();
renderButton();
renderDropdown();
}
// Save current selection as a preset
function savePreset(name) {
// Build paths array from current selection
var paths = Array.from(window.app.selectedGroupingFolders);
// Upsert preset
var existingIndex = presets.findIndex(p => p.name === name);
if (existingIndex >= 0) {
presets[existingIndex] = { name: name, paths: paths };
} else {
presets.push({ name: name, paths: paths });
}
saveToStorage();
activePresetName = name;
isNamingMode = false;
renderButton();
renderDropdown();
}
// Delete a preset by name
function deletePreset(name) {
presets = presets.filter(p => p.name !== name);
if (activePresetName === name) {
activePresetName = null;
}
saveToStorage();
renderButton();
renderDropdown();
}
// Check if current selection differs from active preset
function checkDirty() {
if (activePresetName === null) return;
var preset = presets.find(p => p.name === activePresetName);
if (!preset) return;
var currentPaths = new Set(window.app.selectedGroupingFolders);
var presetPaths = new Set(preset.paths || []);
// Compare sets
var dirty = currentPaths.size !== presetPaths.size ||
!Array.from(currentPaths).every(p => presetPaths.has(p));
if (dirty) {
renderButton();
}
}
// Get minimum depth of grouping folders (for top-level Only)
function getMinDepth() {
if (window.app.groupingFolders.length === 0) return 1;
return Math.min.apply(null, window.app.groupingFolders.map(f => f.path.split('/').length));
}
// Render the preset button label
function renderButton() {
var btn = document.getElementById('presetBtn');
if (!btn) return;
if (activePresetName !== null) {
// Check if dirty
var preset = presets.find(p => p.name === activePresetName);
var dirty = false;
if (preset) {
var currentPaths = new Set(window.app.selectedGroupingFolders);
var presetPaths = new Set(preset.paths || []);
dirty = currentPaths.size !== presetPaths.size ||
!Array.from(currentPaths).every(p => presetPaths.has(p));
}
btn.textContent = '▾ ' + activePresetName + (dirty ? '*' : '');
} else {
btn.textContent = '▾ Presets';
}
}
// Escape HTML for safe insertion
function escapeHtml(text) {
var div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
// Render the dropdown panel
function renderDropdown() {
var dropdown = document.getElementById('presetDropdown');
if (!dropdown) return;
var minDepth = getMinDepth();
// Build presets list HTML
var presetsHtml = '';
if (presets.length === 0) {
presetsHtml = '
No saved presets
';
} else {
presetsHtml = presets.map(preset => {
var escapedName = escapeHtml(preset.name);
return (
'' +
'' + escapedName + '' +
'' +
'
'
);
}).join('');
}
// Build project checkboxes HTML
var projectsHtml = '';
window.app.groupingFolders.forEach(folder => {
// Only include top-level folders (minDepth)
var pathParts = folder.path.split('/');
if (pathParts.length !== minDepth) return;
var isSelected = window.app.selectedGroupingFolders.has(folder.path);
var escapedPath = escapeHtml(folder.path);
var escapedName = escapeHtml(folder.name);
projectsHtml += (
'' +
'' +
'
'
);
});
// Footer HTML
var footerHtml = '';
if (activePresetName !== null) {
// Check if dirty
var preset = presets.find(p => p.name === activePresetName);
var dirty = false;
if (preset) {
var currentPaths = new Set(window.app.selectedGroupingFolders);
var presetPaths = new Set(preset.paths || []);
dirty = currentPaths.size !== presetPaths.size ||
!Array.from(currentPaths).every(p => presetPaths.has(p));
}
if (isNamingMode) {
footerHtml = (
''
);
} else if (dirty) {
footerHtml = (
''
);
} else {
footerHtml = (
''
);
}
} else {
// No active preset — disabled if nothing selected
var selectedCount = window.app.selectedGroupingFolders.size;
var disabledAttr = selectedCount === 0 ? ' disabled' : '';
footerHtml = (
''
);
}
dropdown.innerHTML = (
'' +
'
Saved Presets:
' +
'
' + presetsHtml + '
' +
'
' +
'' +
'' +
'
Projects:
' +
'
' + projectsHtml + '
' +
'
' +
footerHtml
);
}
// Toggle dropdown visibility
function toggleDropdown() {
var dropdown = document.getElementById('presetDropdown');
if (isOpen) {
closeDropdown();
} else {
isOpen = true;
if (dropdown) dropdown.classList.remove('hidden');
renderDropdown();
}
}
// Close dropdown
function closeDropdown() {
isOpen = false;
var dropdown = document.getElementById('presetDropdown');
if (dropdown) dropdown.classList.add('hidden');
isNamingMode = false;
}
// Set up event delegation on dropdown
function setupDropdownDelegation() {
var dropdown = document.getElementById('presetDropdown');
if (!dropdown) return;
dropdown.addEventListener('click', function(e) {
// Close on clicks inside dropdown
e.stopPropagation();
// Preset item click — load preset (do NOT close dropdown)
var presetItem = e.target.closest('.preset-item');
if (presetItem && !e.target.classList.contains('preset-delete')) {
var name = presetItem.getAttribute('data-name');
if (name) loadPreset(name);
return;
}
// Delete button
var deleteBtn = e.target.closest('.preset-delete');
if (deleteBtn) {
e.stopPropagation();
var name = deleteBtn.getAttribute('data-name');
if (name) deletePreset(name);
return;
}
// Checkbox click
var checkbox = e.target.closest('.preset-checkbox');
if (checkbox) {
var path = checkbox.getAttribute('data-path');
if (path) {
if (checkbox.checked) {
window.app.selectedGroupingFolders.add(path);
} else {
window.app.selectedGroupingFolders.delete(path);
}
window.app.modules.app.updateFolderSelectionState('groupingFoldersList');
window.app.modules.app.renderTransmittalFolders();
window.app.modules.filtering.applyFilters();
checkDirty();
renderButton();
renderDropdown(); // Re-render to update checkbox states and footer
}
return;
}
// Save button (not in naming mode)
var saveBtn = e.target.closest('.preset-save-btn');
if (saveBtn && !isNamingMode) {
if (saveBtn.getAttribute('data-disabled') !== 'true') {
isNamingMode = true;
renderDropdown();
}
return;
}
// Update button — save current selection as active preset
var updateBtn = e.target.closest('.preset-update-btn');
if (updateBtn) {
if (activePresetName) savePreset(activePresetName);
return;
}
// Save as New button
var saveNewBtn = e.target.closest('.preset-save-new-btn');
if (saveNewBtn) {
isNamingMode = true;
renderDropdown();
return;
}
// Confirm name input
var confirmBtn = e.target.closest('.preset-confirm-name');
if (confirmBtn) {
var input = dropdown.querySelector('.preset-name-input');
if (input && input.value.trim()) {
savePreset(input.value.trim());
}
return;
}
// Cancel name input
var cancelBtn = e.target.closest('.preset-cancel-name');
if (cancelBtn) {
isNamingMode = false;
renderDropdown();
return;
}
});
// Keydown on name input
dropdown.addEventListener('keydown', function(e) {
var input = e.target.closest('.preset-name-input');
if (!input) return;
if (e.key === 'Enter') {
e.stopPropagation();
if (input.value.trim()) {
savePreset(input.value.trim());
}
} else if (e.key === 'Escape') {
e.stopPropagation();
isNamingMode = false;
renderDropdown();
}
});
}
// Handle outside click to close dropdown
function setupOutsideClickHandler() {
document.addEventListener('click', function(e) {
var section = document.getElementById('presetSection');
var dropdown = document.getElementById('presetDropdown');
if (isOpen && section && dropdown && !section.contains(e.target)) {
closeDropdown();
}
});
}
// Initialize presets module — called after first scan completes
function init() {
// Idempotent: skip if button listener already attached
var btn = document.getElementById('presetBtn');
if (!btn || btn.dataset.presetInit) return;
btn.dataset.presetInit = '1';
btn.addEventListener('click', function(e) {
e.stopPropagation();
toggleDropdown();
});
setupDropdownDelegation();
setupOutsideClickHandler();
loadFromStorage();
renderButton();
}
// Register module
window.app.modules.presets = {
init: init,
loadPreset: loadPreset,
savePreset: savePreset,
deletePreset: deletePreset,
checkDirty: checkDirty,
renderButton: renderButton,
toggleDropdown: toggleDropdown,
closeDropdown: closeDropdown
};
})();