import { InspectorControls } from "@wordpress/block-editor"; import { PanelBody, TextControl, RangeControl, SelectControl, ToggleControl, } from "@wordpress/components"; import { __ } from "@wordpress/i18n"; import { useEffect, useRef } from "@wordpress/element"; import ServerSideRender from "@wordpress/server-side-render"; import { ClassificationMultiSelect } from "../components/ClassificationMultiSelect"; import { migrateNumericCsvPairToIds } from "../utils/migrateTaxonomyIds"; interface TourBlockAttributes { order: "desc" | "asc"; featured: boolean; featured_priority: "" | "featured" | "new" | "limited"; per_page: number; columns: number; title: string; show_pagination: boolean; destinationIds: number[]; activityIds: number[]; categoryIds: number[]; difficultyIds: number[]; destination_ids?: string; destination?: string; activity_ids?: string; activity?: string; category_ids?: string; category?: string; difficulty?: string; price_min: string; price_max: string; duration_min: string; duration_max: string; search: string; } interface EditProps { attributes: TourBlockAttributes; setAttributes: (attrs: Partial) => void; } function normalizeIds(arr: number[] | undefined): number[] { return Array.isArray(arr) ? [...new Set(arr.map((n) => parseInt(String(n), 10)).filter((n) => n > 0))] : []; } export default function Edit({ attributes, setAttributes }: EditProps) { const migratedOnce = useRef(false); useEffect(() => { if (migratedOnce.current) { return; } migratedOnce.current = true; const clears: Partial = {}; let destIds = normalizeIds(attributes.destinationIds); if (destIds.length === 0) { destIds = migrateNumericCsvPairToIds( attributes.destination_ids, attributes.destination, ); if (destIds.length) { clears.destination = ""; clears.destination_ids = ""; } } let actIds = normalizeIds(attributes.activityIds); if (actIds.length === 0) { actIds = migrateNumericCsvPairToIds( attributes.activity_ids, attributes.activity, ); if (actIds.length) { clears.activity = ""; clears.activity_ids = ""; } } let catIds = normalizeIds(attributes.categoryIds); if (catIds.length === 0) { catIds = migrateNumericCsvPairToIds( attributes.category_ids, attributes.category, ); if (catIds.length) { clears.category = ""; clears.category_ids = ""; } } let diffIds = normalizeIds(attributes.difficultyIds); if (diffIds.length === 0) { const fromDiff = migrateNumericCsvPairToIds(attributes.difficulty, ""); diffIds = fromDiff; if (fromDiff.length) { clears.difficulty = ""; } } // Back-compat: migrate legacy `featured: true` to featured_priority="featured" // so existing block instances reflect the value in the new dropdown. if (attributes.featured && !attributes.featured_priority) { clears.featured_priority = "featured"; clears.featured = false; } const next: Partial = { ...clears }; if (destIds.length) { next.destinationIds = destIds; } if (actIds.length) { next.activityIds = actIds; } if (catIds.length) { next.categoryIds = catIds; } if (diffIds.length) { next.difficultyIds = diffIds; } const touched = Object.keys(next).filter( (key) => next[key as keyof typeof next] !== undefined, ).length > 0; if (touched) { setAttributes(next); } // eslint-disable-next-line react-hooks/exhaustive-deps -- one-time migrate from legacy serialized attributes }, [setAttributes]); const destinationIds = normalizeIds(attributes.destinationIds); const activityIds = normalizeIds(attributes.activityIds); const categoryIds = normalizeIds(attributes.categoryIds); const difficultyIds = normalizeIds(attributes.difficultyIds); return ( <> setAttributes({ title: value })} /> setAttributes({ order: value as "asc" | "desc" }) } /> setAttributes({ per_page: value || 10 })} min={1} max={50} /> setAttributes({ columns: value !== undefined && value !== null ? value : 3, }) } min={1} max={6} /> setAttributes({ featured_priority: value as TourBlockAttributes["featured_priority"], // Keep legacy `featured` boolean in sync for back-compat // (existing block instances saved with featured=true). featured: value === "featured", }) } /> setAttributes({ show_pagination: value })} /> setAttributes({ destinationIds: ids })} /> setAttributes({ activityIds: ids })} /> setAttributes({ categoryIds: ids })} /> setAttributes({ difficultyIds: ids })} /> setAttributes({ search: v })} /> setAttributes({ price_min: v })} /> setAttributes({ price_max: v })} /> setAttributes({ duration_min: v })} /> setAttributes({ duration_max: v })} />
); }