PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.16
Yatra – Travel Booking & Tour Operator Software v3.0.16
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 2.0.1 All 84 releases
← All changes | resources/js/pages/AttributeForm.tsx +44 -15 3.0.2.6 → 3.0.16 View file →
@@ -23,8 +23,9 @@
23 23 } from "../components/ui/card";
24 24 import { ConditionalRender } from "../components/ui/conditional-render";
25 25 import { Switch } from "../components/ui/switch";
26 26 import { IconPicker } from "../components/ui/icon-picker";
27 +import type { IconPickerValue } from "../lib/icon-picker-types";
27 28
28 29 type FieldOptionRow = { label: string; value: string };
29 30
30 31 function parseFieldOptionRows(raw: unknown): FieldOptionRow[] {
@@ -70,8 +71,49 @@
70 71 }
71 72 return {};
72 73 }
73 74
75 +/** Map API / DB icon field to IconPicker state (must keep `provider` for Font Awesome). */
76 +function iconFromAttributeApiRaw(raw: unknown): IconPickerValue | null {
77 + if (raw == null || raw === "") {
78 + return null;
79 + }
80 + let ic: unknown = raw;
81 + if (typeof ic === "string") {
82 + const t = ic.trim();
83 + if (t.startsWith("{")) {
84 + try {
85 + ic = JSON.parse(t) as unknown;
86 + } catch {
87 + return t ? { type: "icon", value: t, provider: "yatra" } : null;
88 + }
89 + } else if (t !== "") {
90 + return { type: "icon", value: t, provider: "yatra" };
91 + } else {
92 + return null;
93 + }
94 + }
95 + if (typeof ic !== "object" || ic === null || Array.isArray(ic)) {
96 + return null;
97 + }
98 + const io = ic as { type?: string; value?: unknown; provider?: string };
99 + const val =
100 + io.value !== undefined && io.value !== null ? String(io.value) : "";
101 + if (io.type === "image") {
102 + if (!val) {
103 + return null;
104 + }
105 + return { type: "image", value: val };
106 + }
107 + if (val === "") {
108 + return null;
109 + }
110 + const p = io.provider;
111 + const provider =
112 + p === "fa-solid" || p === "fa-regular" || p === "yatra" ? p : "yatra";
113 + return { type: "icon", value: val, provider };
114 +}
115 +
74 116 type AttributeStatusUi = "publish" | "draft" | "trash";
75 117
76 118 function normalizeAttributeStatusForForm(raw: unknown): AttributeStatusUi {
77 119 const s = typeof raw === "string" ? raw.trim().toLowerCase() : "";
@@ -84,12 +126,9 @@
84 126 interface AttributeFormData {
85 127 name: string;
86 128 slug: string;
87 129 description: string;
88 - icon: {
89 - type: "icon" | "image";
90 - value: string;
91 - } | null;
130 + icon: IconPickerValue | null;
92 131 field_type: string;
93 132 field_option_rows: FieldOptionRow[];
94 133 default_value: string;
95 134 placeholder: string;
@@ -361,19 +400,9 @@
361 400 const convertedData: AttributeFormData = {
362 401 name: String(finalAttribute.name ?? ""),
363 402 slug: String(finalAttribute.slug ?? ""),
364 403 description: String(finalAttribute.description ?? ""),
365 - icon: (() => {
366 - const ic = finalAttribute.icon;
367 - if (!ic || typeof ic !== "object" || Array.isArray(ic)) {
368 - return null;
369 - }
370 - const io = ic as { type?: string; value?: string };
371 - return {
372 - type: io.type === "image" ? "image" : "icon",
373 - value: String(io.value ?? ""),
374 - };
375 - })(),
404 + icon: iconFromAttributeApiRaw(finalAttribute.icon),
376 405 field_type: String(finalAttribute.field_type ?? "text_field"),
377 406 field_option_rows: (() => {
378 407 const rows = parseFieldOptionRows(finalAttribute.field_options);
379 408 return rows.length > 0