@mulmoclaude/collection-plugin 0.5.17 → 0.5.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/vue/components/CollectionRecordPanel.vue.d.ts.map +1 -1
- package/dist/vue/useCollectionRendering.d.ts +3 -2
- package/dist/vue/useCollectionRendering.d.ts.map +1 -1
- package/dist/vue.cjs +172 -110
- package/dist/vue.cjs.map +1 -1
- package/dist/vue.js +172 -110
- package/dist/vue.js.map +1 -1
- package/package.json +1 -1
package/dist/vue.js
CHANGED
|
@@ -1880,82 +1880,90 @@ var _hoisted_13$4 = {
|
|
|
1880
1880
|
key: 0,
|
|
1881
1881
|
class: "text-rose-500 font-bold"
|
|
1882
1882
|
};
|
|
1883
|
-
var _hoisted_14$4 =
|
|
1883
|
+
var _hoisted_14$4 = [
|
|
1884
|
+
"id",
|
|
1885
|
+
"onUpdate:modelValue",
|
|
1886
|
+
"required",
|
|
1887
|
+
"data-testid"
|
|
1888
|
+
];
|
|
1889
|
+
var _hoisted_15$4 = { value: "" };
|
|
1890
|
+
var _hoisted_16$4 = ["value"];
|
|
1891
|
+
var _hoisted_17$4 = {
|
|
1884
1892
|
key: 0,
|
|
1885
1893
|
class: "inline-flex items-center gap-2.5 text-sm text-slate-700 cursor-pointer select-none"
|
|
1886
1894
|
};
|
|
1887
|
-
var
|
|
1895
|
+
var _hoisted_18$4 = [
|
|
1888
1896
|
"id",
|
|
1889
1897
|
"onUpdate:modelValue",
|
|
1890
1898
|
"data-testid",
|
|
1891
1899
|
"onChange"
|
|
1892
1900
|
];
|
|
1893
|
-
var
|
|
1901
|
+
var _hoisted_19$3 = [
|
|
1894
1902
|
"id",
|
|
1895
1903
|
"onUpdate:modelValue",
|
|
1896
1904
|
"required",
|
|
1897
1905
|
"data-testid"
|
|
1898
1906
|
];
|
|
1899
|
-
var
|
|
1900
|
-
var
|
|
1901
|
-
var
|
|
1907
|
+
var _hoisted_20$3 = { value: "" };
|
|
1908
|
+
var _hoisted_21$3 = ["value"];
|
|
1909
|
+
var _hoisted_22$3 = [
|
|
1902
1910
|
"id",
|
|
1903
1911
|
"onUpdate:modelValue",
|
|
1904
1912
|
"required",
|
|
1905
1913
|
"data-testid"
|
|
1906
1914
|
];
|
|
1907
|
-
var
|
|
1908
|
-
var
|
|
1909
|
-
var
|
|
1910
|
-
var
|
|
1915
|
+
var _hoisted_23$3 = { value: "" };
|
|
1916
|
+
var _hoisted_24$2 = ["value"];
|
|
1917
|
+
var _hoisted_25$2 = ["data-testid"];
|
|
1918
|
+
var _hoisted_26$2 = {
|
|
1911
1919
|
key: 0,
|
|
1912
1920
|
class: "overflow-hidden border border-slate-200 rounded-lg shadow-sm"
|
|
1913
1921
|
};
|
|
1914
|
-
var
|
|
1915
|
-
var
|
|
1916
|
-
var
|
|
1917
|
-
var
|
|
1918
|
-
var _hoisted_28$1 = ["onUpdate:modelValue", "required"];
|
|
1919
|
-
var _hoisted_29$1 = { value: "" };
|
|
1920
|
-
var _hoisted_30$1 = ["value"];
|
|
1922
|
+
var _hoisted_27$2 = { class: "w-full text-xs text-slate-600 bg-white" };
|
|
1923
|
+
var _hoisted_28$1 = { class: "bg-slate-50 border-b border-slate-200 text-slate-500 font-bold uppercase tracking-wider" };
|
|
1924
|
+
var _hoisted_29$1 = { class: "divide-y divide-slate-100" };
|
|
1925
|
+
var _hoisted_30$1 = ["onUpdate:modelValue", "onChange"];
|
|
1921
1926
|
var _hoisted_31$1 = ["onUpdate:modelValue", "required"];
|
|
1922
1927
|
var _hoisted_32$1 = { value: "" };
|
|
1923
1928
|
var _hoisted_33$1 = ["value"];
|
|
1924
|
-
var _hoisted_34$1 =
|
|
1929
|
+
var _hoisted_34$1 = ["onUpdate:modelValue", "required"];
|
|
1930
|
+
var _hoisted_35$1 = { value: "" };
|
|
1931
|
+
var _hoisted_36$1 = ["value"];
|
|
1932
|
+
var _hoisted_37$1 = {
|
|
1925
1933
|
key: 3,
|
|
1926
1934
|
class: "relative flex items-center"
|
|
1927
1935
|
};
|
|
1928
|
-
var
|
|
1929
|
-
var
|
|
1930
|
-
var
|
|
1936
|
+
var _hoisted_38$1 = { class: "absolute left-1.5 text-[10px] text-slate-400 font-bold pr-1 border-r border-slate-200" };
|
|
1937
|
+
var _hoisted_39$1 = ["onUpdate:modelValue", "required"];
|
|
1938
|
+
var _hoisted_40$1 = [
|
|
1931
1939
|
"onUpdate:modelValue",
|
|
1932
1940
|
"type",
|
|
1933
1941
|
"step",
|
|
1934
1942
|
"required"
|
|
1935
1943
|
];
|
|
1936
|
-
var
|
|
1937
|
-
var
|
|
1944
|
+
var _hoisted_41$1 = { class: "text-center px-1" };
|
|
1945
|
+
var _hoisted_42$1 = [
|
|
1938
1946
|
"aria-label",
|
|
1939
1947
|
"data-testid",
|
|
1940
1948
|
"onClick"
|
|
1941
1949
|
];
|
|
1942
|
-
var
|
|
1950
|
+
var _hoisted_43$1 = {
|
|
1943
1951
|
key: 1,
|
|
1944
1952
|
class: "text-xs text-slate-400 italic"
|
|
1945
1953
|
};
|
|
1946
|
-
var
|
|
1947
|
-
var
|
|
1954
|
+
var _hoisted_44$1 = ["data-testid", "onClick"];
|
|
1955
|
+
var _hoisted_45$1 = {
|
|
1948
1956
|
key: 4,
|
|
1949
1957
|
class: "relative flex items-center"
|
|
1950
1958
|
};
|
|
1951
|
-
var
|
|
1952
|
-
var
|
|
1959
|
+
var _hoisted_46$1 = { class: "absolute left-3 text-slate-400 font-bold text-xs select-none pr-1.5 border-r border-slate-200" };
|
|
1960
|
+
var _hoisted_47$1 = [
|
|
1953
1961
|
"id",
|
|
1954
1962
|
"onUpdate:modelValue",
|
|
1955
1963
|
"required",
|
|
1956
1964
|
"data-testid"
|
|
1957
1965
|
];
|
|
1958
|
-
var
|
|
1966
|
+
var _hoisted_48$1 = [
|
|
1959
1967
|
"id",
|
|
1960
1968
|
"onUpdate:modelValue",
|
|
1961
1969
|
"type",
|
|
@@ -1964,104 +1972,104 @@ var _hoisted_45$1 = [
|
|
|
1964
1972
|
"disabled",
|
|
1965
1973
|
"data-testid"
|
|
1966
1974
|
];
|
|
1967
|
-
var
|
|
1975
|
+
var _hoisted_49$1 = [
|
|
1968
1976
|
"id",
|
|
1969
1977
|
"onUpdate:modelValue",
|
|
1970
1978
|
"rows",
|
|
1971
1979
|
"required",
|
|
1972
1980
|
"data-testid"
|
|
1973
1981
|
];
|
|
1974
|
-
var
|
|
1975
|
-
var
|
|
1982
|
+
var _hoisted_50$1 = ["data-testid"];
|
|
1983
|
+
var _hoisted_51$1 = {
|
|
1976
1984
|
key: 0,
|
|
1977
1985
|
class: "inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-[10px] font-semibold bg-emerald-50 text-emerald-700 border border-emerald-200/40"
|
|
1978
1986
|
};
|
|
1979
|
-
var
|
|
1987
|
+
var _hoisted_52$1 = {
|
|
1980
1988
|
key: 1,
|
|
1981
1989
|
class: "inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-[10px] font-semibold bg-slate-50 text-slate-400 border border-slate-200/20"
|
|
1982
1990
|
};
|
|
1983
|
-
var
|
|
1991
|
+
var _hoisted_53$1 = {
|
|
1984
1992
|
key: 0,
|
|
1985
1993
|
class: "inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-[10px] font-semibold bg-emerald-50 text-emerald-700 border border-emerald-200/40"
|
|
1986
1994
|
};
|
|
1987
|
-
var
|
|
1995
|
+
var _hoisted_54$1 = {
|
|
1988
1996
|
key: 1,
|
|
1989
1997
|
class: "inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-[10px] font-semibold bg-slate-50 text-slate-400 border border-slate-200/20"
|
|
1990
1998
|
};
|
|
1991
|
-
var
|
|
1999
|
+
var _hoisted_55$1 = {
|
|
1992
2000
|
key: 2,
|
|
1993
2001
|
class: "text-slate-300"
|
|
1994
2002
|
};
|
|
1995
|
-
var
|
|
2003
|
+
var _hoisted_56$1 = [
|
|
1996
2004
|
"href",
|
|
1997
2005
|
"tabindex",
|
|
1998
2006
|
"data-testid",
|
|
1999
2007
|
"onClick",
|
|
2000
2008
|
"onKeydown"
|
|
2001
2009
|
];
|
|
2002
|
-
var
|
|
2010
|
+
var _hoisted_57$1 = {
|
|
2003
2011
|
key: 3,
|
|
2004
2012
|
class: "font-semibold text-slate-900 tabular-nums text-sm"
|
|
2005
2013
|
};
|
|
2006
|
-
var
|
|
2014
|
+
var _hoisted_58$1 = {
|
|
2007
2015
|
key: 4,
|
|
2008
2016
|
class: "inline-block truncate tabular-nums font-bold text-indigo-900 bg-indigo-50/50 px-2 py-0.5 rounded border border-indigo-100/50"
|
|
2009
2017
|
};
|
|
2010
|
-
var
|
|
2018
|
+
var _hoisted_59$1 = {
|
|
2011
2019
|
key: 5,
|
|
2012
2020
|
class: "border border-slate-200/80 rounded-xl overflow-hidden shadow-sm mt-1"
|
|
2013
2021
|
};
|
|
2014
|
-
var
|
|
2015
|
-
var
|
|
2016
|
-
var
|
|
2017
|
-
var
|
|
2022
|
+
var _hoisted_60$1 = { class: "w-full text-[11px] text-slate-600 bg-white" };
|
|
2023
|
+
var _hoisted_61$1 = { class: "bg-slate-50 border-b border-slate-200 text-slate-500 font-bold uppercase tracking-wider" };
|
|
2024
|
+
var _hoisted_62$1 = { class: "divide-y divide-slate-100" };
|
|
2025
|
+
var _hoisted_63$1 = {
|
|
2018
2026
|
key: 0,
|
|
2019
2027
|
class: "material-icons text-emerald-600 text-base"
|
|
2020
2028
|
};
|
|
2021
|
-
var
|
|
2029
|
+
var _hoisted_64$1 = {
|
|
2022
2030
|
key: 1,
|
|
2023
2031
|
class: "text-slate-300"
|
|
2024
2032
|
};
|
|
2025
|
-
var
|
|
2033
|
+
var _hoisted_65$1 = {
|
|
2026
2034
|
key: 6,
|
|
2027
2035
|
class: "text-slate-400 italic"
|
|
2028
2036
|
};
|
|
2029
|
-
var
|
|
2037
|
+
var _hoisted_66$1 = {
|
|
2030
2038
|
key: 7,
|
|
2031
2039
|
class: "bg-slate-50 rounded-xl p-4 border border-slate-200/60 text-slate-600 text-xs whitespace-pre-wrap leading-relaxed max-h-[30vh] overflow-y-auto"
|
|
2032
2040
|
};
|
|
2033
|
-
var
|
|
2041
|
+
var _hoisted_67$1 = [
|
|
2034
2042
|
"src",
|
|
2035
2043
|
"alt",
|
|
2036
2044
|
"data-testid"
|
|
2037
2045
|
];
|
|
2038
|
-
var
|
|
2039
|
-
var
|
|
2040
|
-
var
|
|
2046
|
+
var _hoisted_68$1 = ["href", "data-testid"];
|
|
2047
|
+
var _hoisted_69$1 = ["href", "data-testid"];
|
|
2048
|
+
var _hoisted_70$1 = [
|
|
2041
2049
|
"href",
|
|
2042
2050
|
"data-testid",
|
|
2043
2051
|
"onClick"
|
|
2044
2052
|
];
|
|
2045
|
-
var
|
|
2053
|
+
var _hoisted_71$1 = {
|
|
2046
2054
|
key: 13,
|
|
2047
2055
|
class: "text-slate-800 font-semibold"
|
|
2048
2056
|
};
|
|
2049
|
-
var
|
|
2057
|
+
var _hoisted_72$1 = {
|
|
2050
2058
|
key: 0,
|
|
2051
2059
|
class: "col-span-full text-xs font-semibold text-red-600 bg-red-50 border border-red-100 p-2.5 rounded-xl"
|
|
2052
2060
|
};
|
|
2053
|
-
var
|
|
2061
|
+
var _hoisted_73$1 = {
|
|
2054
2062
|
key: 1,
|
|
2055
2063
|
class: "mt-5 pt-4 border-t border-slate-200/60",
|
|
2056
2064
|
"data-testid": "collections-detail-chat"
|
|
2057
2065
|
};
|
|
2058
|
-
var
|
|
2066
|
+
var _hoisted_74$1 = {
|
|
2059
2067
|
class: "block text-[10px] font-bold text-slate-400 uppercase tracking-wider mb-1.5",
|
|
2060
2068
|
for: "collections-detail-chat-input"
|
|
2061
2069
|
};
|
|
2062
|
-
var
|
|
2063
|
-
var
|
|
2064
|
-
var
|
|
2070
|
+
var _hoisted_75$1 = { class: "flex items-end gap-2" };
|
|
2071
|
+
var _hoisted_76$1 = ["placeholder", "onKeydown"];
|
|
2072
|
+
var _hoisted_77$1 = ["disabled"];
|
|
2065
2073
|
//#endregion
|
|
2066
2074
|
//#region src/vue/components/CollectionRecordPanel.vue
|
|
2067
2075
|
var CollectionRecordPanel_default = /* @__PURE__ */ defineComponent({
|
|
@@ -2110,12 +2118,17 @@ var CollectionRecordPanel_default = /* @__PURE__ */ defineComponent({
|
|
|
2110
2118
|
emit("itemChat", message);
|
|
2111
2119
|
chatMessage.value = "";
|
|
2112
2120
|
}
|
|
2113
|
-
const embedViews = computed(() => props.render.embedViews.value);
|
|
2114
2121
|
/** The record the read-only displays render from: the live draft while
|
|
2115
2122
|
* editing (so non-editable cells like derived/embed preview the in-flight
|
|
2116
2123
|
* values), else the open record. Always an object so `[key]` lookups are
|
|
2117
2124
|
* safe in the template. */
|
|
2118
2125
|
const detailRecord = computed(() => editing.value ? props.liveDerived ?? props.liveRecord ?? {} : props.viewing ?? {});
|
|
2126
|
+
const embedViews = computed(() => props.render.embedViewsFor(detailRecord.value));
|
|
2127
|
+
const embedOwnedKeys = computed(() => {
|
|
2128
|
+
const keys = /* @__PURE__ */ new Set();
|
|
2129
|
+
for (const field of Object.values(props.collection.schema.fields)) if (field.type === "embed" && field.idField) keys.add(field.idField);
|
|
2130
|
+
return keys;
|
|
2131
|
+
});
|
|
2119
2132
|
/** Title for the header: the create label, the edited record's id, or the
|
|
2120
2133
|
* open record's title — same h2 slot in every mode. */
|
|
2121
2134
|
const headerTitle = computed(() => {
|
|
@@ -2148,8 +2161,9 @@ var CollectionRecordPanel_default = /* @__PURE__ */ defineComponent({
|
|
|
2148
2161
|
* cell appears or disappears on toggle: respect the `when` predicate
|
|
2149
2162
|
* (against the active record) and hide the primary key except while
|
|
2150
2163
|
* creating. */
|
|
2151
|
-
function cellVisible(field) {
|
|
2164
|
+
function cellVisible(field, key) {
|
|
2152
2165
|
if (field.primary && editing.value?.mode !== "create") return false;
|
|
2166
|
+
if (embedOwnedKeys.value.has(key)) return false;
|
|
2153
2167
|
return fieldVisible(field, detailRecord.value);
|
|
2154
2168
|
}
|
|
2155
2169
|
/** Mirror of the create-mode primary-key carve-out: drop the HTML5
|
|
@@ -2160,6 +2174,12 @@ var CollectionRecordPanel_default = /* @__PURE__ */ defineComponent({
|
|
|
2160
2174
|
if (editing.value?.mode === "create" && field.primary === true) return false;
|
|
2161
2175
|
return true;
|
|
2162
2176
|
}
|
|
2177
|
+
/** Required flag for an embed's per-record picker — read off the storage
|
|
2178
|
+
* field it writes (`idField`), since the embed itself stores nothing. */
|
|
2179
|
+
function embedPickerRequired(field) {
|
|
2180
|
+
const target = field.idField ? props.collection.schema.fields[field.idField] : void 0;
|
|
2181
|
+
return target ? isFieldRequiredInUi(target) : false;
|
|
2182
|
+
}
|
|
2163
2183
|
/** Tailwind fill/text/border classes tinting an enum `<select>` by its current
|
|
2164
2184
|
* value's colour (palette, or notification red/amber/grey when the field is
|
|
2165
2185
|
* the schema's notifyWhen target). */
|
|
@@ -2237,53 +2257,65 @@ var CollectionRecordPanel_default = /* @__PURE__ */ defineComponent({
|
|
|
2237
2257
|
]))]),
|
|
2238
2258
|
!editing.value && __props.actionError ? (openBlock(), createElementBlock("p", _hoisted_10$5, toDisplayString(__props.actionError), 1)) : createCommentVNode("", true),
|
|
2239
2259
|
createElementVNode("div", _hoisted_11$5, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.collection.schema.fields, (field, key) => {
|
|
2240
|
-
return openBlock(), createElementBlock(Fragment, { key }, [cellVisible(field) ? (openBlock(), createElementBlock("div", {
|
|
2260
|
+
return openBlock(), createElementBlock(Fragment, { key }, [cellVisible(field, String(key)) ? (openBlock(), createElementBlock("div", {
|
|
2241
2261
|
key: 0,
|
|
2242
2262
|
class: normalizeClass(["flex flex-col gap-1.5", colSpanClass(field)])
|
|
2243
2263
|
}, [createElementVNode("label", {
|
|
2244
2264
|
class: "text-[10px] font-bold text-slate-400 uppercase tracking-wider flex items-center gap-1",
|
|
2245
2265
|
for: `collections-field-${key}`
|
|
2246
|
-
}, [createTextVNode(toDisplayString(field.label) + " ", 1), editing.value && field.required ? (openBlock(), createElementBlock("span", _hoisted_13$4, "*")) : createCommentVNode("", true)], 8, _hoisted_12$5), editing.value &&
|
|
2266
|
+
}, [createTextVNode(toDisplayString(field.label) + " ", 1), editing.value && field.required ? (openBlock(), createElementBlock("span", _hoisted_13$4, "*")) : createCommentVNode("", true)], 8, _hoisted_12$5), editing.value && field.type === "embed" && field.idField ? withDirectives((openBlock(), createElementBlock("select", {
|
|
2267
|
+
key: 0,
|
|
2268
|
+
id: `collections-field-${key}`,
|
|
2269
|
+
"onUpdate:modelValue": ($event) => editing.value.text[field.idField] = $event,
|
|
2270
|
+
required: embedPickerRequired(field),
|
|
2271
|
+
class: "w-full rounded-xl border border-slate-200 px-3 py-2 text-xs bg-slate-50 hover:bg-slate-50/50 focus:bg-white focus:border-indigo-500 focus:ring-2 focus:ring-indigo-500/20 focus:outline-none transition-all cursor-pointer font-medium text-slate-700",
|
|
2272
|
+
"data-testid": `collections-input-${key}`
|
|
2273
|
+
}, [createElementVNode("option", _hoisted_15$4, toDisplayString(unref(t)("collectionsView.selectPlaceholder")), 1), (openBlock(true), createElementBlock(Fragment, null, renderList(__props.render.embedOptions(field.to ?? ""), (opt) => {
|
|
2274
|
+
return openBlock(), createElementBlock("option", {
|
|
2275
|
+
key: opt.slug,
|
|
2276
|
+
value: opt.slug
|
|
2277
|
+
}, toDisplayString(opt.display), 9, _hoisted_16$4);
|
|
2278
|
+
}), 128))], 8, _hoisted_14$4)), [[vModelSelect, editing.value.text[field.idField]]]) : editing.value && isEditableType(field.type) ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [field.type === "boolean" ? (openBlock(), createElementBlock("label", _hoisted_17$4, [withDirectives(createElementVNode("input", {
|
|
2247
2279
|
id: `collections-field-${key}`,
|
|
2248
2280
|
"onUpdate:modelValue": ($event) => editing.value.bool[key] = $event,
|
|
2249
2281
|
type: "checkbox",
|
|
2250
2282
|
class: "h-5 w-5 rounded border-slate-300 text-indigo-600 focus:ring-indigo-500/20 cursor-pointer",
|
|
2251
2283
|
"data-testid": `collections-input-${key}`,
|
|
2252
2284
|
onChange: ($event) => markBoolTouched(String(key))
|
|
2253
|
-
}, null, 40,
|
|
2285
|
+
}, null, 40, _hoisted_18$4), [[vModelCheckbox, editing.value.bool[key]]]), createElementVNode("span", { class: normalizeClass(["text-xs font-semibold", editing.value.bool[key] ? "text-indigo-600" : "text-slate-500"]) }, toDisplayString(editing.value.bool[key] ? unref(t)("common.yes") : unref(t)("common.no")), 3)])) : field.type === "ref" && field.to && __props.render.refOptions(field.to).length > 0 ? withDirectives((openBlock(), createElementBlock("select", {
|
|
2254
2286
|
key: 1,
|
|
2255
2287
|
id: `collections-field-${key}`,
|
|
2256
2288
|
"onUpdate:modelValue": ($event) => editing.value.text[key] = $event,
|
|
2257
2289
|
required: isFieldRequiredInUi(field),
|
|
2258
2290
|
class: "w-full rounded-xl border border-slate-200 px-3 py-2 text-xs bg-slate-50 hover:bg-slate-50/50 focus:bg-white focus:border-indigo-500 focus:ring-2 focus:ring-indigo-500/20 focus:outline-none transition-all cursor-pointer font-medium text-slate-700",
|
|
2259
2291
|
"data-testid": `collections-input-${key}`
|
|
2260
|
-
}, [createElementVNode("option",
|
|
2292
|
+
}, [createElementVNode("option", _hoisted_20$3, toDisplayString(unref(t)("collectionsView.selectPlaceholder")), 1), (openBlock(true), createElementBlock(Fragment, null, renderList(__props.render.refOptions(field.to), (opt) => {
|
|
2261
2293
|
return openBlock(), createElementBlock("option", {
|
|
2262
2294
|
key: opt.slug,
|
|
2263
2295
|
value: opt.slug
|
|
2264
|
-
}, toDisplayString(opt.display), 9,
|
|
2265
|
-
}), 128))], 8,
|
|
2296
|
+
}, toDisplayString(opt.display), 9, _hoisted_21$3);
|
|
2297
|
+
}), 128))], 8, _hoisted_19$3)), [[vModelSelect, editing.value.text[key]]]) : field.type === "enum" && Array.isArray(field.values) && field.values.length > 0 ? withDirectives((openBlock(), createElementBlock("select", {
|
|
2266
2298
|
key: 2,
|
|
2267
2299
|
id: `collections-field-${key}`,
|
|
2268
2300
|
"onUpdate:modelValue": ($event) => editing.value.text[key] = $event,
|
|
2269
2301
|
required: isFieldRequiredInUi(field),
|
|
2270
2302
|
class: normalizeClass(["w-full rounded-xl border px-3 py-2 text-xs focus:bg-white focus:border-indigo-500 focus:ring-2 focus:ring-indigo-500/20 focus:outline-none transition-all cursor-pointer font-medium", enumControlClass(String(key), editing.value.text[key])]),
|
|
2271
2303
|
"data-testid": `collections-input-${key}`
|
|
2272
|
-
}, [createElementVNode("option",
|
|
2304
|
+
}, [createElementVNode("option", _hoisted_23$3, toDisplayString(unref(t)("collectionsView.selectPlaceholder")), 1), (openBlock(true), createElementBlock(Fragment, null, renderList(field.values, (value) => {
|
|
2273
2305
|
return openBlock(), createElementBlock("option", {
|
|
2274
2306
|
key: value,
|
|
2275
2307
|
value
|
|
2276
|
-
}, toDisplayString(value), 9,
|
|
2277
|
-
}), 128))], 10,
|
|
2308
|
+
}, toDisplayString(value), 9, _hoisted_24$2);
|
|
2309
|
+
}), 128))], 10, _hoisted_22$3)), [[vModelSelect, editing.value.text[key]]]) : field.type === "table" && field.of ? (openBlock(), createElementBlock("div", {
|
|
2278
2310
|
key: 3,
|
|
2279
2311
|
class: "border border-slate-200 bg-slate-50/30 rounded-xl p-4 space-y-3",
|
|
2280
2312
|
"data-testid": `collections-table-${key}`
|
|
2281
|
-
}, [editing.value.table[key] && editing.value.table[key].length > 0 ? (openBlock(), createElementBlock("div",
|
|
2313
|
+
}, [editing.value.table[key] && editing.value.table[key].length > 0 ? (openBlock(), createElementBlock("div", _hoisted_26$2, [createElementVNode("table", _hoisted_27$2, [createElementVNode("thead", _hoisted_28$1, [createElementVNode("tr", null, [(openBlock(true), createElementBlock(Fragment, null, renderList(field.of, (subField, subKey) => {
|
|
2282
2314
|
return openBlock(), createElementBlock("th", {
|
|
2283
2315
|
key: subKey,
|
|
2284
2316
|
class: "text-left px-3 py-2 font-bold"
|
|
2285
2317
|
}, toDisplayString(subField.label), 1);
|
|
2286
|
-
}), 128)), _cache[9] || (_cache[9] = createElementVNode("th", { class: "w-9" }, null, -1))])]), createElementVNode("tbody",
|
|
2318
|
+
}), 128)), _cache[9] || (_cache[9] = createElementVNode("th", { class: "w-9" }, null, -1))])]), createElementVNode("tbody", _hoisted_29$1, [(openBlock(true), createElementBlock(Fragment, null, renderList(editing.value.table[key], (row, rowIdx) => {
|
|
2287
2319
|
return openBlock(), createElementBlock("tr", {
|
|
2288
2320
|
key: rowIdx,
|
|
2289
2321
|
class: "hover:bg-slate-50/50"
|
|
@@ -2297,53 +2329,53 @@ var CollectionRecordPanel_default = /* @__PURE__ */ defineComponent({
|
|
|
2297
2329
|
type: "checkbox",
|
|
2298
2330
|
class: "h-4 w-4 rounded border-slate-300 text-indigo-600 focus:ring-indigo-500/20 cursor-pointer",
|
|
2299
2331
|
onChange: ($event) => markRowBoolTouched(row, String(subKey))
|
|
2300
|
-
}, null, 40,
|
|
2332
|
+
}, null, 40, _hoisted_30$1)), [[vModelCheckbox, row.bool[subKey]]]) : subField.type === "enum" && Array.isArray(subField.values) && subField.values.length > 0 ? withDirectives((openBlock(), createElementBlock("select", {
|
|
2301
2333
|
key: 1,
|
|
2302
2334
|
"onUpdate:modelValue": ($event) => row.text[subKey] = $event,
|
|
2303
2335
|
required: subField.required,
|
|
2304
2336
|
class: "w-full rounded-lg border border-slate-200 px-2 py-1 text-xs focus:border-indigo-500 focus:outline-none cursor-pointer bg-slate-50 font-medium"
|
|
2305
|
-
}, [createElementVNode("option",
|
|
2337
|
+
}, [createElementVNode("option", _hoisted_32$1, toDisplayString(unref(t)("collectionsView.selectPlaceholder")), 1), (openBlock(true), createElementBlock(Fragment, null, renderList(subField.values, (value) => {
|
|
2306
2338
|
return openBlock(), createElementBlock("option", {
|
|
2307
2339
|
key: value,
|
|
2308
2340
|
value
|
|
2309
|
-
}, toDisplayString(value), 9,
|
|
2310
|
-
}), 128))], 8,
|
|
2341
|
+
}, toDisplayString(value), 9, _hoisted_33$1);
|
|
2342
|
+
}), 128))], 8, _hoisted_31$1)), [[vModelSelect, row.text[subKey]]]) : subField.type === "ref" && subField.to && __props.render.refOptions(subField.to).length > 0 ? withDirectives((openBlock(), createElementBlock("select", {
|
|
2311
2343
|
key: 2,
|
|
2312
2344
|
"onUpdate:modelValue": ($event) => row.text[subKey] = $event,
|
|
2313
2345
|
required: subField.required,
|
|
2314
2346
|
class: "w-full rounded-lg border border-slate-200 px-2 py-1 text-xs focus:border-indigo-500 focus:outline-none cursor-pointer bg-slate-50 font-medium"
|
|
2315
|
-
}, [createElementVNode("option",
|
|
2347
|
+
}, [createElementVNode("option", _hoisted_35$1, toDisplayString(unref(t)("collectionsView.selectPlaceholder")), 1), (openBlock(true), createElementBlock(Fragment, null, renderList(__props.render.refOptions(subField.to), (opt) => {
|
|
2316
2348
|
return openBlock(), createElementBlock("option", {
|
|
2317
2349
|
key: opt.slug,
|
|
2318
2350
|
value: opt.slug
|
|
2319
|
-
}, toDisplayString(opt.display), 9,
|
|
2320
|
-
}), 128))], 8,
|
|
2351
|
+
}, toDisplayString(opt.display), 9, _hoisted_36$1);
|
|
2352
|
+
}), 128))], 8, _hoisted_34$1)), [[vModelSelect, row.text[subKey]]]) : subField.type === "money" ? (openBlock(), createElementBlock("div", _hoisted_37$1, [createElementVNode("span", _hoisted_38$1, toDisplayString(__props.render.currencySymbol(__props.render.resolveCurrency(subField, __props.liveRecord))), 1), withDirectives(createElementVNode("input", {
|
|
2321
2353
|
"onUpdate:modelValue": ($event) => row.text[subKey] = $event,
|
|
2322
2354
|
type: "number",
|
|
2323
2355
|
step: "0.01",
|
|
2324
2356
|
required: subField.required,
|
|
2325
2357
|
class: "w-full rounded-lg border border-slate-200 pl-6 pr-1.5 py-1 text-xs focus:border-indigo-500 focus:outline-none font-semibold text-slate-800"
|
|
2326
|
-
}, null, 8,
|
|
2358
|
+
}, null, 8, _hoisted_39$1), [[vModelText, row.text[subKey]]])])) : withDirectives((openBlock(), createElementBlock("input", {
|
|
2327
2359
|
key: 4,
|
|
2328
2360
|
"onUpdate:modelValue": ($event) => row.text[subKey] = $event,
|
|
2329
2361
|
type: __props.render.inputTypeFor(subField.type),
|
|
2330
2362
|
step: __props.render.stepFor(subField.type),
|
|
2331
2363
|
required: subField.required,
|
|
2332
2364
|
class: "w-full rounded-lg border border-slate-200 px-2 py-1 text-xs focus:border-indigo-500 focus:outline-none font-medium text-slate-700"
|
|
2333
|
-
}, null, 8,
|
|
2334
|
-
}), 128)), createElementVNode("td",
|
|
2365
|
+
}, null, 8, _hoisted_40$1)), [[vModelDynamic, row.text[subKey]]])]);
|
|
2366
|
+
}), 128)), createElementVNode("td", _hoisted_41$1, [createElementVNode("button", {
|
|
2335
2367
|
type: "button",
|
|
2336
2368
|
class: "h-7 w-7 flex items-center justify-center rounded-lg text-slate-400 hover:text-rose-600 hover:bg-rose-50 transition-colors",
|
|
2337
2369
|
"aria-label": unref(t)("collectionsView.removeRow"),
|
|
2338
2370
|
"data-testid": `collections-table-${key}-remove-${rowIdx}`,
|
|
2339
2371
|
onClick: ($event) => removeTableRow(String(key), rowIdx)
|
|
2340
|
-
}, [..._cache[10] || (_cache[10] = [createElementVNode("span", { class: "material-icons text-base" }, "close", -1)])], 8,
|
|
2341
|
-
}), 128))])])])) : (openBlock(), createElementBlock("p",
|
|
2372
|
+
}, [..._cache[10] || (_cache[10] = [createElementVNode("span", { class: "material-icons text-base" }, "close", -1)])], 8, _hoisted_42$1)])]);
|
|
2373
|
+
}), 128))])])])) : (openBlock(), createElementBlock("p", _hoisted_43$1, toDisplayString(unref(t)("collectionsView.noRows")), 1)), createElementVNode("button", {
|
|
2342
2374
|
type: "button",
|
|
2343
2375
|
class: "inline-flex items-center gap-1 text-xs text-indigo-600 hover:text-indigo-800 font-bold hover:underline",
|
|
2344
2376
|
"data-testid": `collections-table-${key}-add`,
|
|
2345
2377
|
onClick: ($event) => addTableRow(String(key), field.of)
|
|
2346
|
-
}, [_cache[11] || (_cache[11] = createElementVNode("span", { class: "material-icons text-xs" }, "add", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.addRow")), 1)], 8,
|
|
2378
|
+
}, [_cache[11] || (_cache[11] = createElementVNode("span", { class: "material-icons text-xs" }, "add", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.addRow")), 1)], 8, _hoisted_44$1)], 8, _hoisted_25$2)) : field.type === "money" ? (openBlock(), createElementBlock("div", _hoisted_45$1, [createElementVNode("div", _hoisted_46$1, toDisplayString(__props.render.currencySymbol(__props.render.resolveCurrency(field, __props.liveRecord))), 1), withDirectives(createElementVNode("input", {
|
|
2347
2379
|
id: `collections-field-${key}`,
|
|
2348
2380
|
"onUpdate:modelValue": ($event) => editing.value.text[key] = $event,
|
|
2349
2381
|
type: "number",
|
|
@@ -2351,7 +2383,7 @@ var CollectionRecordPanel_default = /* @__PURE__ */ defineComponent({
|
|
|
2351
2383
|
required: isFieldRequiredInUi(field),
|
|
2352
2384
|
class: "w-full rounded-xl border border-slate-200 pl-11 pr-3 py-2 text-xs focus:border-indigo-500 focus:ring-2 focus:ring-indigo-500/20 focus:outline-none font-semibold text-slate-800 transition-all",
|
|
2353
2385
|
"data-testid": `collections-input-${key}`
|
|
2354
|
-
}, null, 8,
|
|
2386
|
+
}, null, 8, _hoisted_47$1), [[vModelText, editing.value.text[key]]])])) : [
|
|
2355
2387
|
"string",
|
|
2356
2388
|
"email",
|
|
2357
2389
|
"number",
|
|
@@ -2370,7 +2402,7 @@ var CollectionRecordPanel_default = /* @__PURE__ */ defineComponent({
|
|
|
2370
2402
|
disabled: field.primary === true && (editing.value.mode === "edit" || __props.isSingleton),
|
|
2371
2403
|
class: "w-full rounded-xl border border-slate-200 px-3 py-2 text-xs focus:border-indigo-500 focus:ring-2 focus:ring-indigo-500/20 focus:outline-none disabled:bg-slate-100 disabled:text-slate-400 font-medium text-slate-700 transition-all",
|
|
2372
2404
|
"data-testid": `collections-input-${key}`
|
|
2373
|
-
}, null, 8,
|
|
2405
|
+
}, null, 8, _hoisted_48$1)), [[vModelDynamic, editing.value.text[key]]]) : withDirectives((openBlock(), createElementBlock("textarea", {
|
|
2374
2406
|
key: 6,
|
|
2375
2407
|
id: `collections-field-${key}`,
|
|
2376
2408
|
"onUpdate:modelValue": ($event) => editing.value.text[key] = $event,
|
|
@@ -2378,11 +2410,11 @@ var CollectionRecordPanel_default = /* @__PURE__ */ defineComponent({
|
|
|
2378
2410
|
required: isFieldRequiredInUi(field),
|
|
2379
2411
|
class: "w-full rounded-xl border border-slate-200 px-3 py-2 text-xs focus:border-indigo-500 focus:ring-2 focus:ring-indigo-500/20 focus:outline-none font-medium text-slate-700 transition-all",
|
|
2380
2412
|
"data-testid": `collections-input-${key}`
|
|
2381
|
-
}, null, 8,
|
|
2382
|
-
key:
|
|
2413
|
+
}, null, 8, _hoisted_49$1)), [[vModelText, editing.value.text[key]]])], 64)) : (openBlock(), createElementBlock("div", {
|
|
2414
|
+
key: 2,
|
|
2383
2415
|
class: "text-xs font-medium text-slate-700 break-words",
|
|
2384
2416
|
"data-testid": `collections-detail-value-${key}`
|
|
2385
|
-
}, [field.type === "toggle" ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [field.field !== void 0 && String(detailRecord.value[field.field] ?? "") === field.onValue ? (openBlock(), createElementBlock("span",
|
|
2417
|
+
}, [field.type === "toggle" ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [field.field !== void 0 && String(detailRecord.value[field.field] ?? "") === field.onValue ? (openBlock(), createElementBlock("span", _hoisted_51$1, [_cache[12] || (_cache[12] = createElementVNode("span", { class: "h-1.5 w-1.5 rounded-full bg-emerald-500" }, null, -1)), createTextVNode(" " + toDisplayString(unref(t)("common.yes")), 1)])) : (openBlock(), createElementBlock("span", _hoisted_52$1, toDisplayString(unref(t)("common.no")), 1))], 64)) : field.type === "boolean" ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [detailRecord.value[key] === true ? (openBlock(), createElementBlock("span", _hoisted_53$1, [_cache[13] || (_cache[13] = createElementVNode("span", { class: "h-1.5 w-1.5 rounded-full bg-emerald-500" }, null, -1)), createTextVNode(" " + toDisplayString(unref(t)("common.yes")), 1)])) : detailRecord.value[key] === false ? (openBlock(), createElementBlock("span", _hoisted_54$1, toDisplayString(unref(t)("common.no")), 1)) : (openBlock(), createElementBlock("span", _hoisted_55$1, "—"))], 64)) : field.type === "ref" && field.to && typeof detailRecord.value[key] === "string" && detailRecord.value[key] ? (openBlock(), createElementBlock("a", {
|
|
2386
2418
|
key: 2,
|
|
2387
2419
|
href: unref(cui).recordHref?.(field.to, String(detailRecord.value[key])),
|
|
2388
2420
|
tabindex: unref(cui).recordHref?.(field.to, String(detailRecord.value[key])) ? void 0 : 0,
|
|
@@ -2391,12 +2423,12 @@ var CollectionRecordPanel_default = /* @__PURE__ */ defineComponent({
|
|
|
2391
2423
|
"data-testid": `collections-detail-ref-${key}`,
|
|
2392
2424
|
onClick: ($event) => unref(activateRefLink)($event, field.to, String(detailRecord.value[key])),
|
|
2393
2425
|
onKeydown: [withKeys(($event) => unref(activateRefLink)($event, field.to, String(detailRecord.value[key])), ["enter"]), withKeys(($event) => unref(activateRefLink)($event, field.to, String(detailRecord.value[key])), ["space"])]
|
|
2394
|
-
}, toDisplayString(__props.render.refDisplay(field.to, String(detailRecord.value[key]))), 41,
|
|
2426
|
+
}, toDisplayString(__props.render.refDisplay(field.to, String(detailRecord.value[key]))), 41, _hoisted_56$1)) : field.type === "money" ? (openBlock(), createElementBlock("span", _hoisted_57$1, toDisplayString(__props.render.formatMoney(detailRecord.value[key], __props.render.resolveCurrency(field, detailRecord.value), __props.locale)), 1)) : field.type === "derived" ? (openBlock(), createElementBlock("span", _hoisted_58$1, toDisplayString(__props.render.derivedDisplay(field, __props.render.evaluateDerivedAgainstItem(field, String(key), detailRecord.value), detailRecord.value)), 1)) : field.type === "table" && field.of && __props.render.hasTableRows(detailRecord.value[key]) ? (openBlock(), createElementBlock("div", _hoisted_59$1, [createElementVNode("table", _hoisted_60$1, [createElementVNode("thead", _hoisted_61$1, [createElementVNode("tr", null, [(openBlock(true), createElementBlock(Fragment, null, renderList(field.of, (subField, subKey) => {
|
|
2395
2427
|
return openBlock(), createElementBlock("th", {
|
|
2396
2428
|
key: subKey,
|
|
2397
2429
|
class: "text-left px-4 py-2 font-bold"
|
|
2398
2430
|
}, toDisplayString(subField.label), 1);
|
|
2399
|
-
}), 128))])]), createElementVNode("tbody",
|
|
2431
|
+
}), 128))])]), createElementVNode("tbody", _hoisted_62$1, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.render.tableRows(detailRecord.value[key]), (row, rowIdx) => {
|
|
2400
2432
|
return openBlock(), createElementBlock("tr", {
|
|
2401
2433
|
key: rowIdx,
|
|
2402
2434
|
class: "hover:bg-slate-50/50"
|
|
@@ -2404,12 +2436,12 @@ var CollectionRecordPanel_default = /* @__PURE__ */ defineComponent({
|
|
|
2404
2436
|
return openBlock(), createElementBlock("td", {
|
|
2405
2437
|
key: subKey,
|
|
2406
2438
|
class: "px-4 py-2 align-middle font-medium"
|
|
2407
|
-
}, [subField.type === "boolean" ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [row[subKey] === true ? (openBlock(), createElementBlock("span",
|
|
2439
|
+
}, [subField.type === "boolean" ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [row[subKey] === true ? (openBlock(), createElementBlock("span", _hoisted_63$1, "check_circle")) : (openBlock(), createElementBlock("span", _hoisted_64$1, "—"))], 64)) : (openBlock(), createElementBlock("span", {
|
|
2408
2440
|
key: 1,
|
|
2409
2441
|
class: normalizeClass([subField.type === "money" ? "font-bold text-slate-800 tabular-nums" : ""])
|
|
2410
2442
|
}, toDisplayString(__props.render.formatSubCell(subField, row[subKey], detailRecord.value)), 3))]);
|
|
2411
2443
|
}), 128))]);
|
|
2412
|
-
}), 128))])])])) : field.type === "table" ? (openBlock(), createElementBlock("span",
|
|
2444
|
+
}), 128))])])])) : field.type === "table" ? (openBlock(), createElementBlock("span", _hoisted_65$1, toDisplayString(unref(t)("collectionsView.noRows")), 1)) : field.type === "markdown" ? (openBlock(), createElementBlock("div", _hoisted_66$1, toDisplayString(__props.render.detailText(detailRecord.value[key])), 1)) : field.type === "embed" && embedViews.value[key] ? (openBlock(), createBlock(CollectionEmbedView_default, {
|
|
2413
2445
|
key: 8,
|
|
2414
2446
|
view: embedViews.value[key],
|
|
2415
2447
|
"field-key": String(key)
|
|
@@ -2419,29 +2451,29 @@ var CollectionRecordPanel_default = /* @__PURE__ */ defineComponent({
|
|
|
2419
2451
|
alt: field.label,
|
|
2420
2452
|
class: "max-h-64 max-w-full object-contain rounded-lg border border-slate-200 bg-slate-50",
|
|
2421
2453
|
"data-testid": `collections-detail-image-${key}`
|
|
2422
|
-
}, null, 8,
|
|
2454
|
+
}, null, 8, _hoisted_67$1)) : field.type !== "file" && __props.render.isExternalUrl(detailRecord.value[key]) ? (openBlock(), createElementBlock("a", {
|
|
2423
2455
|
key: 10,
|
|
2424
2456
|
href: String(detailRecord.value[key]),
|
|
2425
2457
|
target: "_blank",
|
|
2426
2458
|
rel: "noopener noreferrer",
|
|
2427
2459
|
class: "text-blue-600 hover:text-blue-800 font-semibold hover:underline break-all",
|
|
2428
2460
|
"data-testid": `collections-detail-url-${key}`
|
|
2429
|
-
}, toDisplayString(String(detailRecord.value[key])), 9,
|
|
2461
|
+
}, toDisplayString(String(detailRecord.value[key])), 9, _hoisted_68$1)) : field.type === "file" && __props.render.artifactUrl(detailRecord.value[key]) ? (openBlock(), createElementBlock("a", {
|
|
2430
2462
|
key: 11,
|
|
2431
2463
|
href: __props.render.artifactUrl(detailRecord.value[key]) ?? void 0,
|
|
2432
2464
|
target: "_blank",
|
|
2433
2465
|
rel: "noopener noreferrer",
|
|
2434
2466
|
class: "text-blue-600 hover:text-blue-800 font-semibold hover:underline break-all",
|
|
2435
2467
|
"data-testid": `collections-detail-file-${key}`
|
|
2436
|
-
}, toDisplayString(String(detailRecord.value[key])), 9,
|
|
2468
|
+
}, toDisplayString(String(detailRecord.value[key])), 9, _hoisted_69$1)) : field.type === "file" && __props.render.fileRoutePath(detailRecord.value[key]) ? (openBlock(), createElementBlock("a", {
|
|
2437
2469
|
key: 12,
|
|
2438
2470
|
href: __props.render.fileRoutePath(detailRecord.value[key]) ?? void 0,
|
|
2439
2471
|
class: "text-blue-600 hover:text-blue-800 font-semibold hover:underline break-all",
|
|
2440
2472
|
"data-testid": `collections-detail-file-${key}`,
|
|
2441
2473
|
onClick: ($event) => unref(activatePathLink)($event, __props.render.fileRoutePath(detailRecord.value[key]) ?? "")
|
|
2442
|
-
}, toDisplayString(String(detailRecord.value[key])), 9,
|
|
2443
|
-
}), 128)), editing.value && __props.saveError ? (openBlock(), createElementBlock("p",
|
|
2444
|
-
!editing.value ? (openBlock(), createElementBlock("div",
|
|
2474
|
+
}, toDisplayString(String(detailRecord.value[key])), 9, _hoisted_70$1)) : (openBlock(), createElementBlock("span", _hoisted_71$1, toDisplayString(__props.render.formatCell(detailRecord.value[key], field.type)), 1))], 8, _hoisted_50$1))], 2)) : createCommentVNode("", true)], 64);
|
|
2475
|
+
}), 128)), editing.value && __props.saveError ? (openBlock(), createElementBlock("p", _hoisted_72$1, toDisplayString(__props.saveError), 1)) : createCommentVNode("", true)]),
|
|
2476
|
+
!editing.value ? (openBlock(), createElementBlock("div", _hoisted_73$1, [createElementVNode("label", _hoisted_74$1, toDisplayString(unref(t)("collectionsView.itemChatLabel")), 1), createElementVNode("div", _hoisted_75$1, [withDirectives(createElementVNode("textarea", {
|
|
2445
2477
|
id: "collections-detail-chat-input",
|
|
2446
2478
|
"onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => chatMessage.value = $event),
|
|
2447
2479
|
rows: "2",
|
|
@@ -2449,13 +2481,13 @@ var CollectionRecordPanel_default = /* @__PURE__ */ defineComponent({
|
|
|
2449
2481
|
class: "flex-1 bg-slate-50 border border-slate-200/80 rounded-xl px-3 py-2 text-xs placeholder-slate-400 focus:outline-none focus:ring-2 focus:ring-indigo-500/20 focus:border-indigo-500 focus:bg-white transition-all resize-none",
|
|
2450
2482
|
"data-testid": "collections-detail-chat-input",
|
|
2451
2483
|
onKeydown: [withKeys(withModifiers(submitItemChat, ["meta"]), ["enter"]), withKeys(withModifiers(submitItemChat, ["ctrl"]), ["enter"])]
|
|
2452
|
-
}, null, 40,
|
|
2484
|
+
}, null, 40, _hoisted_76$1), [[vModelText, chatMessage.value]]), createElementVNode("button", {
|
|
2453
2485
|
type: "button",
|
|
2454
2486
|
class: "h-8 px-2.5 rounded bg-indigo-600 text-white font-bold text-xs hover:bg-indigo-700 disabled:opacity-50 transition-all shadow-sm shadow-indigo-600/10 flex items-center gap-1 shrink-0",
|
|
2455
2487
|
disabled: !chatMessage.value.trim(),
|
|
2456
2488
|
"data-testid": "collections-detail-chat-send",
|
|
2457
2489
|
onClick: submitItemChat
|
|
2458
|
-
}, [_cache[14] || (_cache[14] = createElementVNode("span", { class: "material-icons text-sm" }, "forum", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.chat")), 1)], 8,
|
|
2490
|
+
}, [_cache[14] || (_cache[14] = createElementVNode("span", { class: "material-icons text-sm" }, "forum", -1)), createElementVNode("span", null, toDisplayString(unref(t)("collectionsView.chat")), 1)], 8, _hoisted_77$1)])])) : createCommentVNode("", true)
|
|
2459
2491
|
]),
|
|
2460
2492
|
_: 1
|
|
2461
2493
|
}, 40, ["data-testid"]);
|
|
@@ -2831,17 +2863,43 @@ function useCollectionRendering(collection, locale) {
|
|
|
2831
2863
|
display
|
|
2832
2864
|
})).sort((left, right) => left.display.localeCompare(right.display));
|
|
2833
2865
|
}
|
|
2834
|
-
|
|
2835
|
-
|
|
2866
|
+
/** Dropdown options for an `embed` field's per-record picker (`idField`):
|
|
2867
|
+
* every record in the target collection, labelled by its name/title (or
|
|
2868
|
+
* primary key). Built from `embedCache` so it works for embed targets
|
|
2869
|
+
* that aren't also `ref` targets (the profile collection, say). */
|
|
2870
|
+
function embedOptions(targetSlug) {
|
|
2871
|
+
const data = embedCache.value[targetSlug];
|
|
2872
|
+
if (!data) return [];
|
|
2873
|
+
const { fields, primaryKey } = data.schema;
|
|
2874
|
+
const displayField = "name" in fields ? "name" : "title" in fields ? "title" : primaryKey;
|
|
2875
|
+
return data.items.map((item) => {
|
|
2876
|
+
const slug = String(item[primaryKey] ?? "");
|
|
2877
|
+
const labelRaw = item[displayField];
|
|
2878
|
+
return {
|
|
2879
|
+
slug,
|
|
2880
|
+
display: typeof labelRaw === "string" && labelRaw.length > 0 ? labelRaw : slug
|
|
2881
|
+
};
|
|
2882
|
+
}).filter((opt) => opt.slug.length > 0).sort((left, right) => left.display.localeCompare(right.display));
|
|
2883
|
+
}
|
|
2884
|
+
/** The target record id an embed points at: its fixed `id`, or the
|
|
2885
|
+
* value of the sibling `idField` on the open record (per-record). */
|
|
2886
|
+
function embedTargetId(field, record) {
|
|
2887
|
+
if (field.id) return field.id;
|
|
2888
|
+
if (field.idField && record) return String(record[field.idField] ?? "");
|
|
2889
|
+
return "";
|
|
2890
|
+
}
|
|
2891
|
+
function resolveEmbed(field, record) {
|
|
2892
|
+
if (field.type !== "embed" || !field.to) return {
|
|
2836
2893
|
schema: null,
|
|
2837
2894
|
item: null
|
|
2838
2895
|
};
|
|
2839
|
-
const
|
|
2896
|
+
const targetId = embedTargetId(field, record);
|
|
2897
|
+
const data = targetId ? embedCache.value[field.to] : void 0;
|
|
2840
2898
|
if (!data) return {
|
|
2841
2899
|
schema: null,
|
|
2842
2900
|
item: null
|
|
2843
2901
|
};
|
|
2844
|
-
const item = data.items.find((entry) => String(entry[data.schema.primaryKey] ?? "") ===
|
|
2902
|
+
const item = data.items.find((entry) => String(entry[data.schema.primaryKey] ?? "") === targetId) ?? null;
|
|
2845
2903
|
return {
|
|
2846
2904
|
schema: data.schema,
|
|
2847
2905
|
item
|
|
@@ -2851,12 +2909,15 @@ function useCollectionRendering(collection, locale) {
|
|
|
2851
2909
|
if (field.type === "money") return formatMoney(value, resolveCurrency(field, record), locale.value);
|
|
2852
2910
|
return detailText(value);
|
|
2853
2911
|
}
|
|
2854
|
-
|
|
2912
|
+
/** Build the read-only embed view-models for one record. A function of
|
|
2913
|
+
* the open record (not a bare computed) because a per-record `idField`
|
|
2914
|
+
* embed resolves a different target per row. */
|
|
2915
|
+
function embedViewsFor(record) {
|
|
2855
2916
|
const out = {};
|
|
2856
2917
|
if (!collection.value) return out;
|
|
2857
2918
|
for (const [key, field] of Object.entries(collection.value.schema.fields)) {
|
|
2858
2919
|
if (field.type !== "embed") continue;
|
|
2859
|
-
const { schema, item } = resolveEmbed(field);
|
|
2920
|
+
const { schema, item } = resolveEmbed(field, record);
|
|
2860
2921
|
const rows = [];
|
|
2861
2922
|
if (schema && item) for (const [subKey, subField] of Object.entries(schema.fields)) {
|
|
2862
2923
|
const value = item[subKey];
|
|
@@ -2873,11 +2934,11 @@ function useCollectionRendering(collection, locale) {
|
|
|
2873
2934
|
found: Boolean(item),
|
|
2874
2935
|
rows,
|
|
2875
2936
|
targetSlug: field.to ?? "",
|
|
2876
|
-
recordId: field
|
|
2937
|
+
recordId: embedTargetId(field, record)
|
|
2877
2938
|
};
|
|
2878
2939
|
}
|
|
2879
2940
|
return out;
|
|
2880
|
-
}
|
|
2941
|
+
}
|
|
2881
2942
|
function resolveCurrency(field, record) {
|
|
2882
2943
|
if (field.currencyField && record) {
|
|
2883
2944
|
const code = record[field.currencyField];
|
|
@@ -2968,7 +3029,8 @@ function useCollectionRendering(collection, locale) {
|
|
|
2968
3029
|
loadLinkedCollections,
|
|
2969
3030
|
refDisplay,
|
|
2970
3031
|
refOptions,
|
|
2971
|
-
|
|
3032
|
+
embedOptions,
|
|
3033
|
+
embedViewsFor,
|
|
2972
3034
|
resolveCurrency,
|
|
2973
3035
|
currencySymbol,
|
|
2974
3036
|
formatMoney,
|