PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.4
Yatra – Travel Booking & Tour Operator Software v3.0.4
3.0.17 3.0.16 3.0.15 3.0.14 3.0.14.1 3.0.14.2 3.0.12 3.0.13 3.0.11 3.0.10 3.0.9 3.0.8 3.0.7 3.0.6 3.0.5 3.0.5.1 3.0.4 3.0.3 3.0.2.9 3.0.2.7 3.0.2.8 3.0.2.6 trunk 1.0.0 2.0.0 All 85 releases
yatra / assets / dist / blocks / activity.js

activity.js in Yatra – Travel Booking & Tour Operator Software 3.0.4, at assets/dist/blocks/activity.js

373 lines 11.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 (function(element, blocks, blockEditor, components, i18n, ServerSideRender, apiFetch) {
2 "use strict";
3 const listWrapStyle = {
4 maxHeight: 220,
5 overflowY: "auto",
6 marginTop: 8,
7 padding: "4px 0",
8 border: "1px solid #94949451",
9 borderRadius: 2
10 };
11 function ClassificationMultiSelect({
12 taxonomy,
13 label,
14 help,
15 value,
16 onChange
17 }) {
18 const [items, setItems] = element.useState([]);
19 const [loading, setLoading] = element.useState(true);
20 const [loadError, setLoadError] = element.useState(false);
21 const [search, setSearch] = element.useState("");
22 const [scope, setScope] = element.useState(
23 () => value.length > 0 ? "narrow" : "all"
24 );
25 element.useEffect(() => {
26 if (value.length > 0) {
27 setScope("narrow");
28 }
29 }, [value.length]);
30 element.useEffect(() => {
31 let cancelled = false;
32 setLoading(true);
33 setLoadError(false);
34 apiFetch({
35 path: `/yatra/v1/block-editor/taxonomy-choices?taxonomy=${encodeURIComponent(
36 taxonomy
37 )}`
38 }).then((response) => {
39 if (!cancelled) {
40 setItems(response.items ?? []);
41 }
42 }).catch(() => {
43 if (!cancelled) {
44 setItems([]);
45 setLoadError(true);
46 }
47 }).finally(() => {
48 if (!cancelled) {
49 setLoading(false);
50 }
51 });
52 return () => {
53 cancelled = true;
54 };
55 }, [taxonomy]);
56 const filteredItems = element.useMemo(() => {
57 const q = search.trim().toLowerCase();
58 if (q === "") {
59 return items;
60 }
61 return items.filter((i) => i.name.toLowerCase().includes(q));
62 }, [items, search]);
63 const selectedSet = element.useMemo(() => new Set(value), [value]);
64 const toggleId = (id, checked) => {
65 const next = new Set(selectedSet);
66 if (checked) {
67 next.add(id);
68 } else {
69 next.delete(id);
70 }
71 onChange([...next].sort((a, b) => a - b));
72 };
73 const onScopeChange = (next) => {
74 if (next === "all") {
75 setScope("all");
76 onChange([]);
77 setSearch("");
78 } else {
79 setScope("narrow");
80 }
81 };
82 if (loading) {
83 return /* @__PURE__ */ element.createElement(
84 "fieldset",
85 {
86 className: "yatra-block-taxonomy-field",
87 style: { margin: "0 0 16px", border: "none", padding: 0 }
88 },
89 /* @__PURE__ */ element.createElement("legend", { className: "components-base-control__label", style: { padding: 0 } }, label),
90 /* @__PURE__ */ element.createElement(components.Spinner, null)
91 );
92 }
93 return /* @__PURE__ */ element.createElement(
94 "fieldset",
95 {
96 className: "yatra-block-taxonomy-field",
97 style: { margin: "0 0 16px", border: "none", padding: 0 }
98 },
99 /* @__PURE__ */ element.createElement("legend", { className: "components-base-control__label", style: { padding: 0 } }, label),
100 /* @__PURE__ */ element.createElement(
101 "p",
102 {
103 className: "components-base-control__help",
104 style: { marginTop: 4, marginBottom: 10 }
105 },
106 help
107 ),
108 loadError && /* @__PURE__ */ element.createElement("p", { style: { color: "#b32d2e", fontSize: 12, marginBottom: 8 } }, i18n.__(
109 "Could not load options. Confirm you can edit posts and Yatra REST is available.",
110 "yatra"
111 )),
112 /* @__PURE__ */ element.createElement(
113 components.RadioControl,
114 {
115 label: i18n.__("Listing scope", "yatra"),
116 selected: scope,
117 options: [
118 {
119 label: i18n.__("All published (no restriction)", "yatra"),
120 value: "all"
121 },
122 {
123 label: i18n.__("Only selected (search below)", "yatra"),
124 value: "narrow"
125 }
126 ],
127 onChange: onScopeChange
128 }
129 ),
130 scope === "all" && /* @__PURE__ */ element.createElement("p", { className: "components-base-control__help", style: { marginTop: 4 } }, i18n.__(
131 "The frontend will include every matching published item.",
132 "yatra"
133 )),
134 scope === "narrow" && /* @__PURE__ */ element.createElement(element.Fragment, null, /* @__PURE__ */ element.createElement(
135 components.SearchControl,
136 {
137 label: i18n.sprintf(
138 /* translators: %d = number of loaded taxonomy items */
139 i18n.__("Filter items (%d loaded)", "yatra"),
140 items.length
141 ),
142 hideLabelFromVision: true,
143 placeholder: i18n.__("Type to filter the list…", "yatra"),
144 value: search,
145 onChange: (s) => setSearch(s),
146 __nextHasNoMarginBottom: true
147 }
148 ), value.length > 0 && /* @__PURE__ */ element.createElement("p", { className: "components-base-control__help", style: { marginTop: 4 } }, i18n.sprintf(
149 /* translators: %d = number of selected taxonomy items */
150 i18n.__("%d selected", "yatra"),
151 value.length
152 )), items.length === 0 && !loadError ? /* @__PURE__ */ element.createElement("p", { className: "components-base-control__help" }, i18n.__("No published items of this type yet.", "yatra")) : /* @__PURE__ */ element.createElement("div", { role: "group", "aria-label": label, style: listWrapStyle }, filteredItems.length === 0 ? /* @__PURE__ */ element.createElement("p", { style: { padding: "8px 12px", margin: 0, fontSize: 12 } }, i18n.__("No matching items.", "yatra")) : filteredItems.map((item) => {
153 const cid = Number(item.id);
154 return /* @__PURE__ */ element.createElement(
155 "div",
156 {
157 key: cid,
158 style: { padding: "2px 8px" }
159 },
160 /* @__PURE__ */ element.createElement(
161 components.CheckboxControl,
162 {
163 label: `${item.name} (${cid})`,
164 checked: selectedSet.has(cid),
165 onChange: (checked) => toggleId(cid, checked === true),
166 __nextHasNoMarginBottom: true
167 }
168 )
169 );
170 })), value.length > 0 && /* @__PURE__ */ element.createElement(
171 components.Button,
172 {
173 variant: "link",
174 style: { paddingLeft: 0, marginTop: 6 },
175 onClick: () => onChange([])
176 },
177 i18n.__("Clear selected", "yatra")
178 ), /* @__PURE__ */ element.createElement("p", { className: "components-base-control__help", style: { marginTop: 6 } }, i18n.__(
179 "If none are checked, the block behaves like “All” (no taxonomy filter).",
180 "yatra"
181 )))
182 );
183 }
184 function migrateNumericCsvPairToIds(legacyA, legacyB) {
185 const raw = [legacyA ?? "", legacyB ?? ""].find(
186 (s) => String(s).trim() !== ""
187 );
188 if (raw === void 0) {
189 return [];
190 }
191 const parts = String(raw).split(",").map((s) => s.trim()).filter(Boolean);
192 const ids = [];
193 for (const p of parts) {
194 if (!/^\d+$/.test(p)) {
195 return [];
196 }
197 const n = parseInt(p, 10);
198 if (n > 0) {
199 ids.push(n);
200 }
201 }
202 return [...new Set(ids)];
203 }
204 function normalizeIds(arr) {
205 return Array.isArray(arr) ? [...new Set(arr.map((n) => parseInt(String(n), 10)).filter((n) => n > 0))] : [];
206 }
207 function Edit({ attributes: attributes2, setAttributes }) {
208 const migratedOnce = element.useRef(false);
209 element.useEffect(() => {
210 if (migratedOnce.current) {
211 return;
212 }
213 migratedOnce.current = true;
214 let ids = normalizeIds(attributes2.activityIds);
215 if (ids.length === 0) {
216 ids = migrateNumericCsvPairToIds(attributes2.activity_ids, attributes2.activity);
217 }
218 if (ids.length === 0) {
219 return;
220 }
221 setAttributes({
222 activityIds: ids,
223 activity: "",
224 activity_ids: ""
225 });
226 }, [setAttributes]);
227 const activityIds = normalizeIds(attributes2.activityIds);
228 return /* @__PURE__ */ element.createElement(element.Fragment, null, /* @__PURE__ */ element.createElement(blockEditor.InspectorControls, null, /* @__PURE__ */ element.createElement(components.PanelBody, { title: i18n.__("Activity Settings", "yatra"), initialOpen: true }, /* @__PURE__ */ element.createElement(
229 components.TextControl,
230 {
231 label: i18n.__("Title", "yatra"),
232 value: attributes2.title,
233 onChange: (value) => setAttributes({ title: value })
234 }
235 ), /* @__PURE__ */ element.createElement(
236 components.SelectControl,
237 {
238 label: i18n.__("Order", "yatra"),
239 value: attributes2.order,
240 options: [
241 { label: i18n.__("Ascending", "yatra"), value: "asc" },
242 { label: i18n.__("Descending", "yatra"), value: "desc" }
243 ],
244 onChange: (value) => setAttributes({ order: value })
245 }
246 ), /* @__PURE__ */ element.createElement(
247 components.RangeControl,
248 {
249 label: i18n.__("Number of Activities", "yatra"),
250 value: attributes2.per_page,
251 onChange: (value) => setAttributes({
252 per_page: value !== void 0 && value !== null ? value : 10
253 }),
254 min: 1,
255 max: 50
256 }
257 ), /* @__PURE__ */ element.createElement(
258 components.RangeControl,
259 {
260 label: i18n.__("Columns", "yatra"),
261 value: attributes2.columns,
262 onChange: (value) => setAttributes({
263 columns: value !== void 0 && value !== null ? value : 3
264 }),
265 min: 1,
266 max: 6
267 }
268 ), /* @__PURE__ */ element.createElement(
269 components.ToggleControl,
270 {
271 label: i18n.__("Show pagination", "yatra"),
272 checked: attributes2.show_pagination,
273 onChange: (value) => setAttributes({ show_pagination: value })
274 }
275 ), /* @__PURE__ */ element.createElement(
276 ClassificationMultiSelect,
277 {
278 taxonomy: "activity",
279 label: i18n.__("Activities to show", "yatra"),
280 help: i18n.__(
281 'Use "All published" or narrow with search and checkboxes.',
282 "yatra"
283 ),
284 value: activityIds,
285 onChange: (ids) => setAttributes({ activityIds: ids })
286 }
287 ))), /* @__PURE__ */ element.createElement("div", { className: "yatra-block-editor-preview" }, /* @__PURE__ */ element.createElement(
288 ServerSideRender,
289 {
290 block: "yatra/activity",
291 attributes: attributes2,
292 key: JSON.stringify(attributes2)
293 }
294 )));
295 }
296 const $schema = "https://schemas.wp.org/trunk/block.json";
297 const apiVersion = 3;
298 const name = "yatra/activity";
299 const title = "Activity";
300 const category = "yatra";
301 const icon = "universal-access";
302 const description = "Display activity listings with customizable options";
303 const keywords = [
304 "activity",
305 "adventure",
306 "yatra"
307 ];
308 const textdomain = "yatra";
309 const attributes = {
310 order: {
311 type: "string",
312 "default": "asc"
313 },
314 columns: {
315 type: "number",
316 "default": 3
317 },
318 per_page: {
319 type: "number",
320 "default": 10
321 },
322 title: {
323 type: "string",
324 "default": "Activity Listings"
325 },
326 show_pagination: {
327 type: "boolean",
328 "default": true
329 },
330 activityIds: {
331 type: "array",
332 "default": []
333 }
334 };
335 const supports = {
336 html: false,
337 inserter: true,
338 align: [
339 "wide",
340 "full"
341 ]
342 };
343 const editorScript = "yatra-activity-block-editor";
344 const blockMetadata = {
345 $schema,
346 apiVersion,
347 name,
348 title,
349 category,
350 icon,
351 description,
352 keywords,
353 textdomain,
354 attributes,
355 supports,
356 editorScript
357 };
358 const {
359 $schema: _$schema,
360 editorScript: _$editorScript,
361 ...metadata
362 } = blockMetadata;
363 if (blocks.getBlockType(metadata.name)) {
364 blocks.unregisterBlockType(metadata.name);
365 }
366 blocks.registerBlockType(metadata.name, {
367 ...metadata,
368 edit: Edit,
369 save: () => null
370 });
371 })(wp.element, wp.blocks, wp.blockEditor, wp.components, wp.i18n, wp.serverSideRender, wp.apiFetch);
372 //# sourceMappingURL=activity.js.map
373