Update planner search and planner editor
This commit is contained in:
@@ -20,6 +20,27 @@ const PREP_TIME_MAX = 120;
|
||||
const PREP_TIME_STEP = 5;
|
||||
const PREP_TIME_MIN_GAP = PREP_TIME_STEP;
|
||||
const FILTER_RECIPE_BLUR = 'blur(3px) saturate(0.94)';
|
||||
const FILTER_CONTEXTS = {
|
||||
recipes: {
|
||||
anchorShellId: 'recipe-search-shell',
|
||||
buttonId: 'recipe-filter-btn',
|
||||
getState: () => getFilterState(),
|
||||
applyState: (nextState) => applyFilters(nextState),
|
||||
showSlots: true,
|
||||
},
|
||||
plannerPicker: {
|
||||
anchorShellId: 'planner-picker-search-shell',
|
||||
buttonId: 'planner-picker-filter-btn',
|
||||
getState: () => window.getPlannerPickerFilterState?.() || ({
|
||||
slots: [],
|
||||
tags: [],
|
||||
minMinutes: PREP_TIME_MIN,
|
||||
maxMinutes: PREP_TIME_MAX,
|
||||
}),
|
||||
applyState: (nextState) => window.applyPlannerPickerFilters?.(nextState),
|
||||
showSlots: false,
|
||||
},
|
||||
};
|
||||
|
||||
function escapeHtml(s) {
|
||||
return String(s)
|
||||
@@ -61,7 +82,7 @@ export function getFilterHTML() {
|
||||
outline: none;
|
||||
}
|
||||
</style>
|
||||
<div id="filter-view" class="absolute inset-0 z-[55] hidden opacity-0 transition-opacity duration-150" style="pointer-events:none; background:rgba(0,0,0,0.5) !important; background-image:none !important;" aria-hidden="true">
|
||||
<div id="filter-view" class="absolute inset-0 z-[70] hidden opacity-0 transition-opacity duration-150" style="pointer-events:none; background:rgba(0,0,0,0.5) !important; background-image:none !important;" aria-hidden="true">
|
||||
<div id="filter-panel" class="absolute flex flex-col overflow-hidden rounded-[1.5rem] border" style="background:${FILTER_SURFACE} !important; background-image:none !important; border-color:${FILTER_BORDER} !important; opacity:0; transform:translateY(-0.5rem) scale(0.98); transform-origin:top center; transition:${FILTER_PANEL_TRANSITION}; box-shadow:0 18px 40px rgba(0,0,0,0.34), 0 4px 12px rgba(0,0,0,0.18); width:min(calc(100% - 1.5rem), 22rem);">
|
||||
<div class="pointer-events-none absolute inset-x-0 top-0 h-px" style="background:rgba(242,239,232,0.12);" aria-hidden="true"></div>
|
||||
<div class="shrink-0 px-3.5 pt-3 pb-2 flex justify-end" style="background:${FILTER_SURFACE} !important; background-image:none !important;">
|
||||
@@ -71,7 +92,7 @@ export function getFilterHTML() {
|
||||
</div>
|
||||
|
||||
<div id="filter-panel-body" class="min-h-0 flex-1 overflow-y-auto no-scrollbar px-4 pb-4 space-y-2.5" style="background:${FILTER_SURFACE} !important; background-image:none !important;">
|
||||
<section class="p-3.5" style="background:${FILTER_SURFACE} !important; background-image:none !important;">
|
||||
<section id="filter-slot-section" class="p-3.5" style="background:${FILTER_SURFACE} !important; background-image:none !important;">
|
||||
<p class="text-[10px] font-bold uppercase tracking-wider mb-3" style="color:${FILTER_TEXT_MUTED};">Pora posiłku</p>
|
||||
<div id="filter-slot-chips" class="flex flex-wrap gap-2"></div>
|
||||
</section>
|
||||
@@ -132,6 +153,11 @@ let localTags = [];
|
||||
let localMinMinutes = PREP_TIME_MIN;
|
||||
let localMaxMinutes = PREP_TIME_MAX;
|
||||
let closeTimer = null;
|
||||
let activeFilterContext = 'recipes';
|
||||
|
||||
function getActiveFilterConfig() {
|
||||
return FILTER_CONTEXTS[activeFilterContext] || FILTER_CONTEXTS.recipes;
|
||||
}
|
||||
|
||||
function normalizeTimeRange(minMinutes, maxMinutes) {
|
||||
let nextMin = snapTimeValue(minMinutes);
|
||||
@@ -216,9 +242,10 @@ function positionFilterPanel() {
|
||||
const view = document.getElementById('filter-view');
|
||||
const panel = document.getElementById('filter-panel');
|
||||
const body = document.getElementById('filter-panel-body');
|
||||
const searchShell = document.getElementById('recipe-search-shell');
|
||||
const button = document.getElementById('recipe-filter-btn');
|
||||
if (!view || !panel || !button) return;
|
||||
const { anchorShellId, buttonId } = getActiveFilterConfig();
|
||||
const searchShell = document.getElementById(anchorShellId);
|
||||
const button = document.getElementById(buttonId);
|
||||
if (!view || !panel || (!searchShell && !button)) return;
|
||||
|
||||
const viewRect = view.getBoundingClientRect();
|
||||
const anchorRect = (searchShell || button).getBoundingClientRect();
|
||||
@@ -327,9 +354,16 @@ function renderTagChips() {
|
||||
});
|
||||
}
|
||||
|
||||
function syncFilterSections() {
|
||||
const slotSection = document.getElementById('filter-slot-section');
|
||||
if (!slotSection) return;
|
||||
slotSection.classList.toggle('hidden', !getActiveFilterConfig().showSlots);
|
||||
}
|
||||
|
||||
function syncLiveFilters() {
|
||||
applyFilters({
|
||||
slots: localSlots,
|
||||
const config = getActiveFilterConfig();
|
||||
config.applyState?.({
|
||||
slots: config.showSlots ? localSlots : [],
|
||||
tags: localTags,
|
||||
minMinutes: localMinMinutes,
|
||||
maxMinutes: localMaxMinutes,
|
||||
@@ -465,15 +499,17 @@ export function setupFilter() {
|
||||
syncLiveFilters();
|
||||
});
|
||||
|
||||
window.openFilters = () => {
|
||||
if (isFilterPanelOpen()) {
|
||||
window.openFilters = (contextName = 'recipes') => {
|
||||
if (isFilterPanelOpen() && activeFilterContext === contextName) {
|
||||
window.closeFilters();
|
||||
return;
|
||||
}
|
||||
|
||||
const state = getFilterState();
|
||||
localSlots = [...state.slots];
|
||||
localTags = [...state.tags];
|
||||
activeFilterContext = FILTER_CONTEXTS[contextName] ? contextName : 'recipes';
|
||||
const config = getActiveFilterConfig();
|
||||
const state = config.getState?.() || {};
|
||||
localSlots = [...(state.slots || [])];
|
||||
localTags = [...(state.tags || [])];
|
||||
const normalized = normalizeTimeRange(
|
||||
Number.isFinite(state.minMinutes) ? state.minMinutes : PREP_TIME_MIN,
|
||||
Number.isFinite(state.maxMinutes) ? state.maxMinutes : PREP_TIME_MAX,
|
||||
@@ -485,6 +521,7 @@ export function setupFilter() {
|
||||
|
||||
renderSlotChips();
|
||||
renderTagChips();
|
||||
syncFilterSections();
|
||||
|
||||
showFilterPanel();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user